Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Explore all of Roam's Android SDK methods.
Learn how to easily implement Roam location technology.
Get started with Roam by creating a The account gives you access to all our location products, project creation and dashboard with a full overview of your usage and spending.
During the signup process, download the Roam Test App. It’s our demo application for Android and iOS that showcases the basic functionality of Roam location technology.
Read our Roam Docs for Android and iOS for instructions about how to effectively integrate and use our location SDKs and APIs.
To get more information about our products read our or contact our support team.
Explore how to resume a trip on Android with Trips v2.
The Resume Trip method allows you to resume the trip with the previously paused tripID.
The trip response and its parameters are similar to those of the createTrip method.
Explore how to delete a trip on Android with Trips v2.
You can delete the trip irrespective of any trip state. To delete the trip, you need to use the tripID with Roam.deleteTrip("tripId") method.
You can access the delete trip response parameters below:
-keep class com.amazonaws.**
Call this method to periodically pick up a user's location when they are stationary. Customize the time interval in seconds.
By using this method updateLocationWhenStationary
, location will update every x
seconds when the device goes into a stationary state.
Except for time-based custom tracking, this will operate in all tracking modes, including active, passive, balance, and distance based custom tracking.
// Enter update interval in seconds
Roam.updateLocationWhenStationary(int i);
response.getCode()
Integer
The success response code of the method.
response.getMessage()
String
The success response message of the method.
response.getDescription()
String
Error response description of the method.
response.getTrip().getTripId()
String
Unique identifier for the object.
response..getTrip().getIsDeleted()
boolean
Boolean value to determine if the trip has been deleted.
Call this method to update the current location of a user.
Using the updateCurrentLocation
method, you can update the users' current location. You can set the accuracy between 5 to 100 meters (default is 10).
You can now send custom meta-data json values along with updateCurrentLocation
method.
Learn more about the key concepts of Roam location technology.
The fundamental component of Roam location tracking. It is a package of data collected about a users’ location that includes latitude, longitude, altitude, speed, direction, activity, and more.
The Location module defines the desired data flow of a location update. Depending on what you intend to do with the location update we distinguish four different location modules: Tracker, Publisher, Listener, and Processor.
The location update is collected by the GPS via Roam SDK and stored locally on the mobile device. You may use it if you want simple location tracking and store the location data yourself.
The location update is collected by the GPS via Roam SDK, sent from the mobile device to the backend server, and stored in the Roam database. You may use it if you want to store the data on Roam servers and go beyond simple location tracking by accessing other Roam products.
The location listener updates the changes in the location through the server to the mobile device.
The Location Processor processes the location updates stored in the database according to the API calls.
Location tracking mode allows you to customize your location tracking with varying frequencies of updates and levels of battery drain insights. We differentiate three default modes: Active, Reactive, Passive, and one fully customizable.
Explore how to update a trip on Android with Trips v2.
The Update Trip method allows you to update your trip details at any point in time. However, you can update the stop locations as long as the trip has not started. You need to create a new object or update the existing trip, assign it with the RoamTrip()
class and pass the trip object to Roam.updateTrip(trip)
.
The trip response and its parameters are similar to those of the createTrip() method.
There's no need to exclusively specify if the trip is local using a boolean value. The updateTrip() method will check that for you and update the trip details accordingly.
Explore the Trips v2 SDK Methods for Android
Explore how to get the details of a trip on Android with Trips v2.
To get the details of the trip anytime, you can use the Roam.getTrip("tripId") method by passing the tripID.
The trip response and its parameters are similar to those of the createTrip method.
There's no need to exclusively specify if the trip is local or not using a boolean value. The getTrip()
method will check that for you and update the trip details accordingly.
Explore how to get the summary of a trip on Android with Trips v2.
To get a summary of the trip anytime, you can use the Roam.getTripSummary("tripId") method by passing the tripID.
The trip response and its parameters are similar to those of the createTrip()
method.
You don't need to mention if the trip is local trip with a boolean value. The getTripSummary() method will check that for you and return the trip details accordingly.
Explore how to end a trip on Android with Trips v2.
the End Trip method allows you to end the trip with the previously created tripID. If you want to stop tracking, then you can pass stopTracking as true
or false
.
The trip response and its parameters are similar to those of the createTrip method.
Explore how to start a trip on Android with Trips v2.
The Start Trip method allows you to start a planned trip with the previously created tripID.
The trip response and its parameters are similar to those of the createTrip() method.
Explore how to get a user's active trips on iOS with Trips v2.
To get the users' active trips, you can use the Roam.getActiveTrips(isLocal)
method where the value of isLocal is boolean. The value being true returns all the local trips and value being false, returns all active trips created on the server side..
The Get Active trips method returns all the trips in the form of a list. The parameters and responses are similar to those of the createTrip()
method.
Explore the documentation for Roam's Users API.
Explore Roam's Trips v1 API documentation.
Explore how to sync a trip on Android with Trips v2.
Sync Trip allows you to sync a local trip to the server by using tripID.
Roam.syncTrip("tripId", new RoamSyncTripCallback() {
@Override
public void onSuccess(RoamSyncTripResponse response) {
//get sync trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
Roam.syncTrip("tripId", object : RoamSyncTripCallback {
override fun onSuccess(response: RoamSyncTripResponse) {
//get sync trip details
}
override fun onError(error: Error?) {
//get error details
}
})
You can access the sync trip response parameters below:
response.getCode()
Integer
The success response code of the method.
response.getMessage()
String
The success response message of the method.
response.getDescription()
String
The error response description of the method.
response.getData().getTripId()
String
Unique identifier for the object.
response..getData().getIsSynced()
boolean
The boolean value to determine if the trip is synced.
Troubleshooting documentation for iOS.
Coming Soon. Request for beta access if you'd like to try it out.
Coming Soon. Request for beta access if you'd like to try it out.
Explore Roam's Trip v2 API documentation
Roam.resumeTrip("tripId", object : RoamTripCallback {
override fun onSuccess(response: RoamTripResponse) {
//get trip details
}
override fun onError(error: Error?) {
//get error details
}
})
Roam.resumeTrip("tripId", new RoamTripCallback() {
@Override
public void onSuccess(RoamTripResponse response) {
//get trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
Roam.deleteTrip("tripId", object : RoamDeleteTripCallback {
override fun onSuccess(response: RoamDeleteTripResponse) {
//get delete trip details
}
override fun onError(error: Error) {
//get error details
}
})
Roam.deleteTrip("tripId", new RoamDeleteTripCallback() {
@Override
public void onSuccess(RoamDeleteTripResponse response) {
//get delete trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
val data = JSONObject()
data.put("Key", "Value")
val roamPublish = RoamPublish.Builder()
.metadata(data)
.build()
Roam.updateCurrentLocation(DesiredAccuracy, accuracy,roamPublish)
JSONObject data = new JSONObject();
data.put("Key", "Value");
RoamPublish roamPublish = new RoamPublish.Builder()
.metadata(data)
.build();
Roam.updateCurrentLocation(DesiredAccuracy, accuracy,roamPublish);
Roam.updateTrip(trip, object : RoamTripCallback {
override fun onSuccess(response: RoamTripResponse) {
//get trip details
}
override fun onError(error: Error?) {
//get error details
}
})
Roam.updateTrip(trip, new RoamTripCallback() {
@Override
public void onSuccess(RoamTripResponse response) {
//get trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
Roam.getTrip("tripId", object : RoamTripCallback {
override fun onSuccess(response: RoamTripResponse) {
//get trip details
}
override fun onError(error: Error?) {
//get error details
}
})
RoamTrackingMode roamTrackingMode = new RoamTrackingMode.Builder(distanceFilter, stopDuration)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build();
Roam.getTrip("tripId", new RoamTripCallback() {
@Override
public void onSuccess(RoamTripResponse response) {
//get trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
Roam.getTripSummary("tripId", object : RoamTripCallback {
override fun onSuccess(response: RoamTripResponse) {
//get active trip summary details
}
override fun onError(error: Error?) {
//get error details
}
}
Roam.getTripSummary("tripId", new RoamTripCallback() {
@Override
public void onSuccess(RoamTripResponse response) {
//get active trip summary details
}
@Override
public void onError(Error error) {
//get error details
}
});
Roam.endTrip("tripId", true, object : RoamTripCallback {
override fun onSuccess(response: RoamTripResponse) {
//get trip details
}
override fun onError(error: Error?) {
//get error details
}
})
Roam.endTrip("tripId",true, new RoamTripCallback() {
@Override
public void onSuccess(RoamTripResponse response) {
//get trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
Roam.startTrip("tripId", object : RoamTripCallback {
override fun onSuccess(response: RoamTripResponse?) {
//get trip details
}
override fun onError(error: Error?) {
//get error details
}
})
Roam.startTrip("tripId", new RoamTripCallback() {
@Override
public void onSuccess(RoamTripResponse response) {
//get trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
[Roam getActiveTrips:true handler:^(RoamActiveTripResponse * _Nullable, RoamTripError * _Nullable) {
// Access trip response and error here
}];
The first step is to configure the iOS SDK.
[Roam setTrackingInAppState:STATE];
Parameter
Description
STATE
RoamTrackingState.Foreground (or) RoamTrackingState.Background (or)
RoamTrackingState.AlwaysOn
[Roam offlineLocationTracking];
Parameter
Description
Bool
true (default) -- Offline location enabled. false -- Offline location disabled.
For enabling accuracy engine for Passive, Active, and Balanced tracking,
Roam.enableAccuracyEngine()
For Custom tracking modes, you can pass the desired accuracy values in integers ranging from 1-150m.
Roam.enableAccuracyEngine("DESIRED-ACCURACY-VALUE")
For disabling accuracy engine,
Roam.disableAccuracyEngine()
Explore how to start a trip on iOS with Trips v2.
To start a planned trip, you need to pass the tripID with theRoam.endTrip("tripId")
method.
[Roam startTrip:@"tripId" :false handler:^(RoamTripResponse * response, RoamTripError * error) {
// Access end trip response
}];
The trip response and its parameters are similar to those of the createTrip()
method.
Explore how to pause a trip on iOS with Trips v2.
To pause the trip, you need to pass the tripID with the Roam.pauseTrip("tripId")
method.
[Roam pauseTrip:@"tripId" handler:^(RoamTripResponse * response, RoamTripError * error) {
// Access resume trip response
}];
The trip response and its parameters are similar to those of the createTrip()
method.
Explore how to resume a trip on iOS with Trips v2.
To resume the trip, you need to pass the tripID with the Roam.resumeTrip("tripId")
method.
[Roam resumeTrip:@"tripId" handler:^(RoamTripResponse * response, RoamTripError * error) {
// Access resume trip response
}];
The trip response and its parameters are similar to those of the createTrip()
method.
Explore how to get the details of a trip on iOS with Trips v2.
To get the details of the trip anytime, you can use the Roam.getTrip("tripId") method by passing the tripId.
[Roam getTrip:@"tripId" handler:^(RoamTripResponse * response, RoamTripError * error) {
// Access trip response and error here
}];
The trip response and its parameters are similar to those of the createTrip()
method.
There's no need to exclusively specify if the trip is local or not using a boolean value. The getTrip()
method will check that for you and update the trip details accordingly.
Explore how to get the summary of a trip on iOS with Trips v2.
To get a summary of the trip anytime, you can use the Roam.getTripSummary("tripId")
method and pass the tripID.
[Roam getTripSummary:@"tripId" handler:^(RoamTripResponse * response, RoamTripError * error) {
// Access trip response and error here
}];
The trip response and its parameters are similar to those of the createTrip()
method.
Explore all documentation for Android.
Explore the documentation for our Geofencing API
Call this method to get the current location of the user at your desired accuracy level.
Get the current location of the user. You can set the accuracy between 5 and 100 meters (default is 10). This method has two outputs.
Callback Method which returns the current location with a faster response time. However, the accuracy depends on the current GPS connectivity.
Location Receiver which returns the next two location updates which will have higher accuracy compared to the callback and takes time from a few hundred milliseconds to a couple of seconds based on the GPS and network connectivity.
To listen to location updates, create a class that extends RoamReceiver. Then register the receiver by adding a receiver element to the application element in your manifest.
Add the code to the receiver.
To get the current location of the user in the callback, use the following code:
Call the method to update the current location of a user.
Using the updateCurrentLocation
method, you can update the user's current location. You can set the accuracy between 5 and 100 meters (default is 10).
You can now send custom meta-data JSON values along with updateCurrentLocation
method.
Call the method to periodically pick up a user's location when they are stationary. Customize the time interval in seconds.
By using this method updateLocationWhenStationary
, location will update every x
seconds when the device goes into a stationary state.
Except for time-based custom tracking, this will operate in all tracking modes, including active, passive, balance, and distance based custom tracking.
Explore the Trips v2 SDK Methods for iOS.
Explore how to update a trip on iOS with Trips v2.
The Update Trip method allows you to update your trip details at any point in time. However, you can update the stop locations as long as the trip has not started. You need to create a new object or update the existing trip, assign it with the RoamTrip()
class and pass the trip object to Roam.updateTrip(trip)
.
The trip response and its parameters are similar to those of the createTrip() method.
There's no need to exclusively specify if the trip is local using a boolean value. The updateTrip() method will check that for you and update the trip details accordingly.
Explore how to end a trip on iOS with Trips v2.
To end the trip, you need to pass the tripID with the Roam.endTrip("tripId")
method.
The trip response and its parameters are similar to those of the createTrip()
method.
This page describes the Roam authentication model, API endpoints, and error handling while using Roam APIs.
All URLs referenced in the API documentation will have the following base:
REST APIs are served over HTTPS. To ensure data privacy, Roam discourages using unencrypted HTTP requests.
Here are some popular use cases with Roam APIs:
Can be used to view and do much more with your user data.
Enables you to view user count per project.
Enables you to determine the device (iOS/Android) and application from which the hits are coming.
Can create, update, and delete Geofences, and trigger events on the fly
Use geofences to create virtual fences for your structural properties on maps.
Track your users as they enter and exit geofences.
Understand user behavior and usage, as well as visit patterns.
Provides Location APIs to track your users' movement and activities.
Know the users' location in real-time by just calling Roam APIs.
Trips APIs can be used to view your user trips and routes
Track the trip of the user.
Fetch path of the trips along with the routes, mode of transportation, stop points, and offline status.
Roam uses an API Key based authentication passed using a custom headerApi-Key
for the APIs taking into consideration the safety of your API secret keys. We provide APIs on a per-project basis so that the projects are independent of each other's APIs.
Once your application is integrated with the Roam SDK, an account for each user will be created using your app. Information about these users can be tracked through Roam APIs.
Here are the API endpoints available to interact with the user profile data:
Call the method to get the current location of the user at your desired accuracy level.
This method gets the current location of the user. You can set the accuracy between 5 and 100 meters (default is 10).
Our Roam Docs contain instructions on how to integrate and use our location SDKs and APIs. Each section walks you through the step-by-step process with source code, examples, and references.
Roam SDK is a convenient Software Development Kit that helps you easily add to your app without the complexity of REST API calls. Our main product offers accuracy, battery efficiency, and customizable location tracking with the following additional features:
Always-on location tracking to track users’ location at all times regardless of the application state (foreground, background, terminated)
Offline location tracking to track users’ location when they are not connected to the internet.
Location spoofing prevention prevents your users from faking their location.
Location tracking modes to customize the setup and optimize battery usage and data collection frequency.
Our REST APIs allow you to go beyond simple location tracking:
- static and moving geofences with events.
- detailed location information about your users' patterns.
- full trip management for mobility and on-demand services.
- find nearby users and geofences.
Insights APIs are on demand for our enterprise customers. In case you want us to process your location data to know your users Home, Work and POIs, please reach out to our customer support.
<application>
...
<receiver android:name=".LocationReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.roam.android.RECEIVED"/>
</intent-filter>
</receiver>
...
</application>
Roam.getCurrentLocation(DesiredAccuracy, accuracy, object : RoamLocationCallback {
override fun location(location: Location?) {
// Access location data here
}
override fun onFailure(roamError: RoamError) {
// Access Error code and message here
// roamError.code
// roamError.message
}
})
Roam.getCurrentLocation(DesiredAccuracy, accuracy, new RoamLocationCallback(){
@Override
public void location(Location location) {
// Access location data here
}
@Override
public void onFailure(RoamError roamError) {
// Access Error code and message here
// roamError.getCode();
// roamError.getMessage();
}
});
Parameter
Description
DesiredAccuracy
RoamTrackingMode.DesiredAccuracy.HIGH RoamTrackingMode.DesiredAccuracy.MEDIUM RoamTrackingMode.DesiredAccuracy.LOW
Roam.getCurrentLocation(accuracy)
Roam.getCurrentLocation(accuracy);
class LocationReceiver : RoamReceiver() {
override fun onLocationUpdated(context: Context?, roamLocation: RoamLocation?) {
// receive own location updates here
// do something with location data using location
}
}
public class LocationReceiver extends RoamReceiver {
@Override
public void onLocationUpdated(Context context, RoamLocation roamLocation) {
// receive own location updates here
// do something with location data using location
}
}
The first step is to configure the Android SDK.
Roam.setTrackingInAppState(STATE)
Roam.setTrackingInAppState(STATE);
Parameter
Description
STATE
RoamTrackingMode.AppState.FOREGROUND (or)
RoamTrackingMode.AppState.BACKGROUND (or)
RoamTrackingMode.AppState.ALWAYS_ON
Roam.offlineLocationTracking(Boolean)
Roam.offlineLocationTracking(Boolean);
Parameter
Description
Boolean
true (default) -- Offline location enabled. false -- Offline location disabled.
Roam SDKs reject Mock Locations on the device by default.
Roam.allowMockLocation(Boolean)
Roam.allowMockLocation(Boolean);
Parameter
Description
Boolean
false (default) -- Mock location disabled.
true -- Mock location enabled
To enable accuracy engine for Passive, Active, and Balanced tracking
Roam.enableAccuracyEngine()
Roam.enableAccuracyEngine();
For Custom tracking modes, you can pass the desired accuracy values in integers ranging from 1 - 150m.
Roam.enableAccuracyEngine("DESIRED-ACCURACY-VALUE")
Roam.enableAccuracyEngine("DESIRED-ACCURACY-VALUE");
For disabling accuracy engine
Roam.disableAccuracyEngine()
Roam.disableAccuracyEngine();
Use setForegroundNotification
method to notify the user about location tracking in the notification bar. Set ENABLE as true to enable notification and false to disable the notification.
// ENABLE as Boolean (mandatory)
// TITLE as String (mandatory)
// DESCRIPTION as String (mandatory)
// ICON as String (mandatory)
// ACTIVITY_PATH as String (mandatory)
// FOREGROUND_SERVICE_PATH as String (mandatory)
Roam.setForegroundNotification(ENABLE,"TITLE","DESCRIPTION","ICON",
"ACTIVITY_PATH","FOREGROUND_SERVICE_PATH")
// ENABLE as Boolean (mandatory)
// TITLE as String (mandatory)
// DESCRIPTION as String (mandatory)
// ICON as String (mandatory)
// ACTIVITY_PATH as String (mandatory)
// FOREGROUND_SERVICE_PATH as String (mandatory)
Roam.setForegroundNotification(ENABLE,"TITLE","DESCRIPTION","ICON",
"ACTIVITY_PATH","FOREGROUND_SERVICE_PATH");
Explore how to subscribe to a trip on Android with Trips v2.
You can subscribe to a trip using the tripID to get real-time trip data.
Roam.subscribeTrip("tripId");
Roam.subscribeTrip("tripId")
Once you subscribe to the trip, you will receive real time trip data in the listener method of RoamReceiver sub-class.
Listeners are needed to consume the location data from the SDK itself. In order to enable listeners, ensure the following.
To listen to location updates, create a class that extends RoamReceiver. Then, register the receiver by adding a receiver element to the application element in your manifest.
<application>
...
<receiver android:name=".LocationReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.roam.android.RECEIVED"/>
</intent-filter>
</receiver>
...
</application>
Then add the code to the receiver.
public class LocationReceiver extends RoamReceiver {
@Override
public void onLocationUpdated(Context context, RoamLocation roamLocation) {
super.onLocationUpdated(context, roamLocation);
// receive own location updates here
// do something with location data using location
// roamLocation.getActivity();
// roamLocation.getRecordedAt();
// roamLocation.getTimezoneOffset();
// roamLocation.getMetadata();
// roamLocation.getBatteryStatus();
// roamLocation.getNetworkStatus();
// roamLocation.getLocation().getLatitude();
// roamLocation.getLocation().getLongitude();
// roamLocation.getLocation().getBearing();
// roamLocation.getLocation().getAltitude();
// roamLocation.getLocation().getAccuracy();
// roamLocation.getLocation().getSpeed();
// roamLocation.getLocation().getProvider();
// roamLocation.getLocation().getTime();
// roamLocation.getLocation().getVerticalAccuracyMeters();
}
@Override
public void onReceiveTrip(Context context, RoamTripStatus roamTripStatus) {
//get realtime trip data
}
@Override
public void onError(Context context, RoamError roamError) {
// receive error message here
// roamError.getCode());
// roamError.getMessage());
}
}
class LocationReceiver : RoamReceiver() {
override fun onLocationUpdated(context: Context?, roamLocation: RoamLocation?) {
super.onLocationUpdated(context, roamLocation)
// receive own location updates here
// do something with location data using location
// roamLocation.getActivity()
// roamLocation.getRecordedAt()
// roamLocation.getTimezoneOffset()
// roamLocation.getMetadata()
// roamLocation.getBatteryStatus()
// roamLocation.getNetworkStatus()
// roamLocation.getLocation().getLatitude()
// roamLocation.getLocation().getLongitude()
// roamLocation.getLocation().getBearing()
// roamLocation.getLocation().getAltitude()
// roamLocation.getLocation().getAccuracy()
// roamLocation.getLocation().getSpeed()
// roamLocation.getLocation().getProvider()
// roamLocation.getLocation().getTime()
// roamLocation.getLocation().getVerticalAccuracyMeters()
}
override fun onReceiveTrip(context: Context?, roamTripStatus: RoamTripStatus?) {
//get realtime trip data
}
override fun onError(context: Context?, roamError: RoamError?) {
// receive error message here
// roamError.getCode())
// roamError.getMessage())
}
}
You can access the subscribed trip response parameters below:
roamTripStatus.getTripId()
String
Unique identifier for the object.
roamTripStatus.getSpeed()
double
Current speed of the subscribed trip
roamTripStatus.getDistance()
double
The total distance covered by the user for this trip.
roamTripStatus.getDuration()
double
The total duration taken by the user for this trip.
roamTripStatus.getStartedTime()
String
The timestamp of when the trip was started by the user
roamTripStatus.getPace()
double
The current pace of the subscribed trip
roamTripStatus.getLatitude()
double
Current latitude coordinates of the subscribed trip
roamTripStatus.getLongitude()
double
Current longitude coordinates of the subscribed trip
roamTripStatus.getAltitude()
double
Current altitude of the subscribed trip
roamTripStatus.getElevationGain()
double
The elevation gain covered by the user for this trip.
roamTripStatus.getTotalElevation()
double
The total elevation gain covered by the user for this trip.
You can also unsubscribe from the trip using its tripID.
Roam.unsubscribeTrip("tripId")
Explore how to delete a trip on iOS with Trips v2.
You can delete the trip irrespective of any trip state. To delete the trip, you need to use the tripID with the Roam.deleteTrip("tripId")
method.
Roam.deleteTrip("tripId") { response, error in
// Access delete trip response
}
[Roam deleteTrip:@"tripId" handler:^(RoamTripResponse * response, RoamTripError * error) {
// Access delete trip response
}];
You can access the delete trip response parameters below:
response?.code
number
The success response code of the method.
response?.message
string
The success response message of the method.
response?.errorDescription
string
Error response description of the method.
response?.tripId
string
Unique identifier for trip objects.
response?.isDeleted
boolean
Boolean value to determine if the trip has been deleted.
Explore the iOS utility methods related to location permissions.
The Roam SDK is capable of sending push notifications to your users. Click here to get the device token.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Roam.setDeviceToken(deviceToken)
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
[Roam setDeviceToken:deviceToken];
}
Check if the location permissions for the app are enabled.
Roam.isLocationEnabled()
[Roam isLocationEnabled];
By using the locationPermissionStatus
method you can check the location permission status.
Roam.locationPermissionStatus()
[Roam locationPermissionStatus];
Application request for the user location.
Roam.requestLocation()
[Roam requestLocation];
Check whether location tracking has started or not. This method returns a boolean value.
Roam.isLocationTracking()
[Roam isLocationTracking];
By using this method inside the Notification delegate method you can track the campaign's impressions and counts.
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
{
Roam.notificationOpenedHandler(response)
completionHandler()
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
[Roam notificationOpenedHandler:response];
}
Explore how to get a user's active trips on Android with Trips v2.
To get the users' active trips, you can use the Roam.getActiveTrips(isLocal)
method where the value of isLocal is boolean. The value being true returns all the local trips and value being false, returns all active trips created on the server side.
Roam.getActiveTrips(isLocal,new RoamActiveTripsCallback() {
@Override
public void onSuccess(RoamActiveTripsResponse response) {
//get active trips details
}
@Override
public void onError(Error error) {
//get error details
}
});
Roam.getActiveTrips(isLocal, object : RoamActiveTripsCallback {
override fun onSuccess(response: RoamActiveTripsResponse?) {
//get active trips details
}
override fun onError(error: Error?) {
//get error details
}
})
The Get Active trips method returns all the trips in the form of a list. The parameters and responses are similar to those of the createTrip()
method.
https://api.roam.ai/v1/
Roam.getActiveTrips(true) { response, error in
// Access trip response and error here
}
Roam.setTrackingInAppState(STATE)
Roam.offlineLocationTracking(Bool)
Roam.startTrip("tripId") { response, error in
// Access end trip response
}
Roam.pauseTrip("tripId") { response, error in
// Access resume trip response
}
Roam.resumeTrip("tripId") { response, error in
// Access resume trip response
}
Roam.getTrip("tripId") { response, error in
// Access trip response and error here
}
Roam.getTripSummary("tripId") { response, error in
// Access trip response and error here
}
// update current location without meta-data
[Roam updateCurrentLocation:accuracy];
// update current location with meta-data
// Declare meta-data
RoamPublish *publish = [[RoamPublish alloc] init];
NSDictionary *metaData = @{ "key" : "value"};
publish.meta_data = metaData
[Roam updateCurrentLocation:accuracy :publish];
// update current location without meta-data
Roam.updateCurrentLocation(accuracy)
// update the current location with meta-data
// Declare meta-data
let publish = RoamPublish()
let metaData:Dictionary<String,Any> = ["key":value]
publish.meta_data = metaData
Roam.updateCurrentLocation(accuracy, publish)
[Roam updateLocationWhenStationary:<#(interval-in-seconds)#>];
Roam.updateLocationWhenStationary(interval-in-seconds)
[Roam updateTrip handler:^(RoamTripResponse * response, RoamTripError * error) {
// Access trip response and error here
}];
Roam.updateTrip(trip) { response, error in
// Access trip response and error here
}
[Roam endTrip:@"tripId" :false handler:^(RoamTripResponse * response, RoamTripError * error) {
// Access end trip response
}];
Roam.endTrip("tripId") { response, error in
// Access end trip response
}
[Roam getCurrentLocation:accuracy handler:^(CLLocation * location, RoamError * error) {
// location?.coordinate.latitude
// location?.coordinate.longitude
// location?.altitude
// error?.code
// error?.message
}];
Roam.getCurrentLocation(accuracy) { (location, error) in
//location?.coordinate.latitude
//location?.coordinate.longitude
//location?.altitude
// error?.code
// error?.message
}
This API helps you to export trip data in the .gpx format.
GET
https://api.roam.ai/v1/api/trips/export/
trip_id
string
trip_id required to export its data in gpx format. E.g.- 5fdc5470203bda0000abacc0
type
string
format to be given in which data need to be exported. E.g.- gpx
Api-key
string
Auth-key E.g.- 083591a3392c483e838f66ac788126eb
curl --location --request GET 'https://api.roam.ai/v1/api/trips/export/?trip_id=5f44a2fce289b825457e5497&type=gpx' \
--header 'Api-key: <API-KEY>'
This API helps you to delete an existing trip.
DELETE
https://api.roam.ai/v1/api/trips/
trip_id
string
Trip id which needs to be deleted. E.g.- 5cd0299d77aebe2d78758d32
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
curl --location --request DELETE 'https://api.roam.ai/v1/api/trips/?trip_id=<TRIP-ID>' \
--header 'Content-Type: application/json' \
--header 'Api-key: <API-KEY>'
The Create User API creates users corresponding to the project secret API key provided.
Explore how to delete a trip with our Trip API
DELETE
https://api.roam.ai/v2/trips/:id
You can delete the trip via this API. Deleting a trip does not affect any users who have already completed the trip; however the user can't start a previously created trip if it is deleted.
Delete Geofence API allows you to delete already existing geofences for a project.
You can delete the geofence by two options below:
Query Parameters: This can accept only one geofence_id which can be deleted.
Body Parameters: If you want to delete more than one geofence, you can use the body parameters with upto 200 geofence_id at a time.
DELETE
https://api.roam.ai/v1/api/geofence
Single Delete
Bulk Delete
Api-key*
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
app_type*
number
Either 1 or 2 where 1 is for Android and 2 is for iOS
device_token*
string
Device token (can be dummy value initially), the same will be updated once the user is logged in from an actual device.
description
string
The description of the user.
metadata
array
Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
curl --location --request POST 'https://api.roam.ai/v1/api/user/' \
--header 'Api-Key: <YOUR-API-KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"app_type": 1,
"device_token": "your-device-token",
"description": "device description",
"metadata": { }
}'
id*
String
Exports the trip summary with the given ID.
Authorization*
String
Bearer <API-KEY>
curl --location --request DELETE 'https://api.roam.ai/v2/trips/620f4fb7d79b3200007cd92c' \
--header 'Authorization: Bearer dfbbf5d5XXXXcb1166147b87c0544'
geofence_id
string
Delete geofence for this id. E.g.- 5f73326ce5fc231ba4b253eb
Api-key
string
Auth-key E.g.-33223kjhdcscijhb5sdbsdmjsdcbj5f
geofence_id
array
Array of geofence_id to be deleted.
E.g- ["5f73326ce5fc231ba4b253eb", "5f73326ce5fc231ba4b2534f"]
curl --location --request DELETE 'https://api.roam.ai/v1/api/geofence/?geofence_id=5f73326ce5fc231ba4b253eb' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json'
curl --location --request DELETE '{{host}}/v3/api/geofence/' \
--header 'Api-key: xxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"geofence_id": ["615c6cef8ce7db3886f21550", "615c6ce351efb0120dcea364"]
}'
This API lets you update the details of a user.
PUT
https://api.roam.ai/v1/api/user/
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
user_id
string
Enable or disable events data for the given user_id. E.g.- 5d9450ace47bae6d70064a9b
description
string
Update user description. E.g.- “test user”
geofence_events
boolean
Enable or disable geofence_events. E.g.- true
trips_events
boolean
Enable or disable trips_events. E.g.- true
location_events
boolean
Enable or disable location_events. E.g.- true
nearby_events
boolean
Enable or disable nearby_events. E.g.- true
event_listener
boolean
Enable or disable event_listener. E.g.- true
location_listener
boolean
Enable or disable location_listener. E.g.- true
curl --location --request PUT 'https://api.roam.ai/v1/api/user/' \
--header 'Content-Type: application/json' \
--header 'APi-Key: 63598c5b3aa84f14914013709402bbc9' \
--data-raw '{
"user_id": "60b90dd651efb070950db2e0",
"description": "ROAM111",
"metadata" :{"name": "ROAM123" },
"geofence_events": false,
"motion_events": false,
"location_events": false,
"trips_events": false,
"nearby_events": false,
"location_listener": false,
"event_listener": false
}'
This API will provide a list of insights with boundary coordinates of the location, last visit details, type and confidence for the user's home.
GET
https://api.roam.ai/v1/api/insights/home/
user_id
string
Get Home location for the user. E.g.- 5d9450ace47bae6d70064a9b
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
curl --location --request GET 'https://api.roam.ai/v1/api/insights/home/?user_id=5f30d339b36114713d8b610e' \
--header 'Api-key: ee5b950fdf284474a8727409cd12bb3b'
This API will provide a list of insights with boundary coordinates of the location, last visit details, type and confidence for the user’s work.
GET
https://api.roam.ai/v1/api/insights/work/
user_id
string
Get Work location for the user. E.g.- 5d9450ace47bae6d70064a9b
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
curl --location --request GET 'https://api.roam.ai/v1/api/insights/work/?user_id=5f30d339b36114713d8b610e' \
--header 'Api-key: ee5b950fdf284474a8727409cd12bb3b'
Explore the documentation for Roam's Locations API.
Explore how to subscribe to a trip on iOS with Trips v2.
For you to subscribe to a trip, you need to pass the tripID with the Roam.subscribeTrip("tripId")
method.
Once you subscribe to the trip, you will receive real time trip data in the listener methods
In order to subscribe to the trips with the listener method, you need to make sure the below is implemented.
To listen to location updates, create a class that implements RoamDeleagate
and then call Roam.delegate.
Set your RoamDelegate
in a code path that will be initialized and executed in the background. For example, ensure that your AppDelegate
and not the ViewController
implements RoamDelegate
. The reason being, AppDelegate
will be initialized in the background, whereas a ViewController
may not be.
You can access the subscribed trip response parameters below:
You can unsubscribe from trips using the tripID.
Explore how to sync a trip on iOS with Trips v2.
To sync a trip, you need to pass the tripID with the Roam.syncTrip("tripId")
method.
You can access the sync trip response parameters below:
- (void)onReceiveTrip:(RoamTripStatus *)tripStatus {
// Access subscribeTrip response
}
response.tripId
string
Unique identifier for trip objects.
response.speed
double
Current speed of the subscribed trip
response.distance
double
Current distance covered of the subscribed trip
response.duration
double
Current duration taken of the subscribed trip
response.startedTime
string
Timestamp of when the trip was started by the user
response.pace
double
The current pace of the subscribed trip
response.latitude
double
Current latitude coordinates of the subscribed trip
response.longitude
double
Current longitude coordinates of the subscribed trip
Roam.unsubscribeTrip("tripId")
[Roam unsubscribeTrip:@"tripId"];
[Roam subscribeTrip:@"tripId"];
Roam.subscribeTrip("tripId")
import UIKit
import Roam
import CoreLocation
@main
class AppDelegate: UIResponder, UIApplicationDelegate, RoamDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Roam.delegate = self
Roam.initialize("YOUR-SDK-KEY-GOES-HERE")
return true
}
func didUpdateLocation(_ location: RoamLocation) {
// Do something with the user location
// location.userId
// location.activity
// location.timezoneOffset
// location.recordedAt
// location.batteryRemaining
// location.networkStatus
// location.metaData
// location.location.speed
// location.location.horizontalAccuracy
// location.location.verticalAccuracy
// location.location.altitude
// location.location.course
// location.location.coordinate.latitude
// location.location.coordinate.longitude
}
func onReceiveTrip(_ response: RoamTripStatus) {
// Access subscribeTrip response
}
response?.code
number
The success response code of the method.
response?.message
string
The success response message of the method.
response?.messageDescription
string
Error response description of the method.
response?.tripId
string
Unique identifier for the trip object.
response?.isSynced
boolean
Boolean value to determine if the trip is synced.
[Roam syncTrip:@"" handler:^(RoamTripSync * response, RoamTripError * error) {
// Access sync trip response
}];
Roam.syncTrip("tripId") { response, error in
// Access sync trip response
}
This API gives you the filtered list of geofences.
GET
https://api.roam.ai/v1/api/geofence/
user_id
string
Filter the geofence which is enabled for this user_id E.g.- 6073325bcf3e4eba5a1123a
group_id
string
Filter the geofences which is enabled for this group_id E.g.- 6073325bc3fe343ab6c1324b
page_number
integer
This field can be used for getting 10 entries at a time. If the response returns an empty list in the data field, it is safe to assume the pages are exhausted. E.g.-1
start_date
string
Date from when the geofences created to be fetched. E.g.- 2020-09-28
end_date
string
Date till when the data need to be returned. E.g.- 2020-09-29
geofence_id
string
Get the details of one geofence. E.g.- 5f73326ce5fc231ba4b253eb
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
{
"status": true,
"msg": "Success.",
"code": 200,
"data": {
"next_page": null,
"pages": 1,
"prev_page": null,
"geofences": [
{
"geofence_id": "60ee8ea4ffb3fb728c120d8b",
"geometry_type": "circle",
"geometry_radius": 177,
"geometry_center": {
"type": "Point",
"coordinates": [
-72.28122,
42.926042
]
},
"is_enabled": [
true,
"2021-06-10T18:45:00.000",
"2021-06-10T19:29:00.000"
],
"user_ids": [
"6bda16edea01848b3b419163"
],
"is_deleted": false,
"created_at": "2021-07-14T07:13:40.765",
"updated_at": "2021-07-14T07:13:40.765"
},
{
"geofence_id": "60ee8e6effb3fb728c120d8a",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-0.08789347686767579,
51.50619618452938
],
[
-0.0905934768676758,
51.50619618452938
],
[
-0.0905934768676758,
51.503796184529385
],
[
-0.08789347686767579,
51.50619618452938
]
]
]
},
"geometry_type": "polygon",
"geometry_center": {
"type": "Point",
"coordinates": [
-0.08969347686882724,
51.505396185373506
]
},
"is_enabled": [
true,
"2021-06-10T18:45:00.000",
"2021-06-10T19:29:00.000"
],
"is_deleted": false,
"created_at": "2021-07-14T07:12:46.811",
"updated_at": "2021-07-14T07:12:46.811"
}
]
}
}
curl --location --request GET 'https://api.roam.ai/v1/api/geofence/?start_date=2020-09-28&end_date=2020-09-29' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88'
The create Geofence API is responsible for creating geofences for project, users or groups.
POST
https://api.roam.ai/v1/api/geofence/
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
group_ids
array
Enables geofence for the list of users. If group_ids and user_ids are empty then geofence is enabled for all users of the project. E.g.- ["group1","group2"]
user_ids
array
Enables geofence for the list of users. If group_ids and user_ids are empty then geofence is enabled for all users of the project. E.g.-["user1","user2"]
coordinates
array
Mandatory for creating the geofence. E.g.- [ -72.28122, 42.926042 ]
metadata
object
An optional set of custom key-value pairs for the geofence.
geometry_type
string
Defines the type of geometry. E.g.- circle
geometry_radius
integer
Defines the radius of circular geofence in meters. Range 50m to 1000m. (Required only for geometry_type circle. Field value ignored if sent when geometry_type is a polygon.) E.g.- 50m to 1000m max
color_code
string
Defines the color of Geofence and how it is displayed on the dashboard. Type: Hex Code for CSS colors. Note: Pass the code without '#'. E.g.- ffffff
tag
string
Tag the Geofences for future reference and filtering. E.g.- hotel
description
string
Optional description for the geofence. E.g.- This is just a 5 star cool hotel where you can stay.
is_enabled
array
Array with first index depicting whether the geofence is enabled or disabled, second index depicting the start_time and last index depicting the end_time between which the geofence should be active. E.g.- [true,"2021-06-10T20:45:44", "2021-06-15T22:45:33"]
{
"status": true,
"msg": "Geofence created successfully.",
"code": 201,
"data": {
"geofence_id": "5f73326ce5fc231ba4b253eb",
"geometry_radius": 177,
"geometry_center": {
"type": "Point",
"coordinates": [
-72.28122,
42.926042
]
},
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"],
"user_ids": ["6bda16edea01848b3b419163"],
"group_ids": ["5cda16edea00845b3b419173"],
"created_at": "2020-09-29T13:11:08.702",
"updated_at": "2020-09-29T13:11:08.702"
}
}
curl --location --request POST 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '{
"coordinates": [ -72.28122, 42.926042 ] ,
"geometry_radius": 177,
"description": "Roam Amsterdam HQ",
"tag": "Office",
"metadata": {},
"user_ids": ["6bda16edea01848b3b419163"],
"group_ids": ["5cda16edea00845b3b419173"],
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"]
}'
{
"status": true,
"msg": "Success.",
"code": 200,
"data": {
"download_url": "https://geospark-gpx-files.s3.amazonaws.com/5fdc5470203bda0000abacc0.gpx"
}
}
{
"status": true,
"msg": "Trip deleted successfully.",
"code": 200,
"data": null
}
{
"status":true,
"msg":"User tracking initiated successfully.",
"code":201,
"data":{
"user_id":"62135419cc5d8960bf735b3f",
"app_id":"61dfb41b06f8a05d35522133_1",
"description":null,
"geofence_events":false,
"location_events":false,
"trips_events":false,
"nearby_events":false,
"location_listener":false,
"event_listener":false,
"metadata":null,
"sdk_version":"0",
"project_id":"61dfb41b06f8a05d35522133",
"account_id":"61dfb4030dc55a46ac091ad0"
}
}
{
"message": "trip_deleted",
"description": "The trip data is deleted for given id.",
"code": 200,
"trip": {
"id": "61dec6e206f8a019b2402c0b",
"is_deleted": true
}
}
{
"code" : 404,
"message" : "object_not_found",
"description": "The requested object does not exist or already deleted.",
"errors" : [ ]
}
{
"status": true,
"msg": "Geofence deleted successfully.",
"code": 200,
"data": {}
}
{
"status": true,
"msg": "Success.",
"code": 200,
"data": {
"id": "60b90dd651efb070950db2e9",
"account_id": "60af304c51efb03cdde65042",
"app_id": "60af306a8ce7db2392eb7a75_1",
"device_token": "d1_nRSCRgMI:APA91bFgVQ8BJqVJsuGF7CbFDfyiMSLgL6c0mW_GHVfeBcjEraRA6lJfreGqKSMzsvNE7ARJn-8V8_mbyL_Bwyy0ScKtjauarg84MyZlgRahszRVPr69-FgdvSx5xi699YGcXz8nfTnb",
"device_uuid": null,
"description": "ROAM111",
"brand": "xiaomi",
"model": "Redmi Note 7",
"group_id": null,
"os_version": "28",
"sdk_version": "3.1.6",
"device_arn": "arn:aws:sns:us-east-1:218937252071:endpoint/GCM/app_60af306a8ce7db2392eb7a75_1_a678d41d-a66f-442b-90e5-1564b6c88c34/5b73758f-cc96-373a-a2dc-400d8c8f5685",
"geofence_events": false,
"motion_events": false,
"location_events": false,
"trips_events": false,
"nearby_events": false,
"location_listener": false,
"event_listener": false,
"metadata": {
"name": "ROAM123"
},
"is_deleted": false,
"created_at": "2021-06-03T17:13:58.830",
"updated_at": "2021-07-02T07:44:38.781"
}
}
{
"status": true,
"msg": "Success.",
"code": 200,
"data": {
"user_id": "5f30d339b36114713d8b610e",
"app_id": "5ed0e627372279444054d310_2",
"home": [
{
"id": "5f3fa9c6b361144e2fbb94fe",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
4.891497893193696,
52.353609136438145
],
...
...
[
4.891816390473826,
52.353578324857374
]
]
]
},
"last_visited": {
"id": "5f36a5529b3043b3240c2c92",
"coordinates": {
"type": "Point",
"coordinates": [
4.891546992613287,
52.353057861328125
]
},
"accuracy": null,
"altitude": 1.3552925316616893,
"recorded_at": "2021-06-14T14:53:06.320",
"started_at": null,
"created_at": "2021-06-14T14:53:06.505"
},
"tz_offset": "+0200",
"confidence": "Medium",
"type": "home",
"created_at": "2021-06-21T11:02:27.831"
}
]
}
}
{
"status": true,
"msg": "Success.",
"code": 200,
"data": {
"user_id": "5f30d339b36114713d8b610e",
"app_id": "5ed0e627372279444054d310_2",
"work": [
{
"id": "5f3fa9c6b361144e2fbb94ff",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
4.907285075174389,
52.36281525332162
],
...
...
[
4.907603638813551,
52.36278444174071
]
]
]
},
"last_visited": {
"id": "5f3bc1fc118fe82b1a623751",
"coordinates": {
"type": "Point",
"coordinates": [
4.907237518324856,
52.36199951171875
]
},
"accuracy": null,
"altitude": -0.5668405294418335,
"recorded_at": "2021-06-17T08:31:24.594",
"started_at": null,
"created_at": "2021-06-18T11:56:44.237"
},
"tz_offset": "+0200",
"confidence": "Medium",
"type": "work",
"created_at": "2021-06-21T11:02:28.295"
}
]
}
}
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
user_id
string
user_id to which the trip is to be reassigned E.g.- 5d9450ace47bae6d70064a9q
trip_id
string
Trip id which needs to be modified. E.g.- 5d9450ace47bae6d70064a9b
origins
array
Origin location in [long, lat] format. E.g.- [[77.677270, 12.914131]]
destinations
array
Destination location in [long, lat] format. E.g.- [[77.700475, 12.957005]]
curl --location --request PUT 'https://api.roam.ai/v1/api/trips/' \
--header 'Api-key: <API-KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"trip_id": "<TRIP-ID>",
"destinations": [[77.700475, 12.957005]]
}'
{
"status": true,
"msg": "Success.",
"code": 201,
"data": [
{
"id": "<ID>",
"origins": [
{
"id": "<ID>",
"trip_id": "<TRIP-ID>",
"created_at": "2021-06-22T06:00:34.264",
"updated_at": "2021-06-22T06:00:34.269",
"coordinates": {
"type": "Point",
"coordinates": [
77.622977,
12.917042
]
},
"loc_type": "origin"
}
],
"destinations": [
{
"id": "<ID>",
"trip_id": "<TRIP-ID>",
"created_at": "2021-06-22T06:01:44.680",
"updated_at": "2021-06-22T06:01:44.687",
"coordinates": {
"type": "Point",
"coordinates": [
77.700475,
12.957005
]
},
"loc_type": "destination"
}
],
"events": [
{
"id": "<ID>",
"trip_id": "<TRIP-ID>",
"user_id": "<USER-ID>",
"event_type": "motion:trip:created",
"created_at": "2021-06-22T06:00:35.210",
"is_deleted": false,
"event_source": "motion:trip",
"event_version": "1.0"
},
{
"id": "<ID>",
"trip_id": "<TRIP-ID>",
"user_id": "<USER-ID>",
"event_type": "motion:trip:created",
"created_at": "2021-06-22T06:01:42.606",
"is_deleted": false,
"event_source": "motion:trip",
"event_version": "1.0"
}
],
"user_id": "<USER-ID>",
"is_started": false,
"is_ended": false,
"is_deleted": false,
"created_at": "2021-06-22T06:00:34.261",
"updated_at": "2021-06-22T06:01:44.699"
}
]
}
Events APIs are used to fetch the list of events generated by the users with ability to filter the results based on various parameters.
In progress...
Tracking is a process of identifying the location of a mobile phone whether stationary or moving. Our solution includes collecting latitude and longitude coordinates from GPS satellites through the GPS chip present in smartphones with iOS or Android operating systems. Along with the geographical coordinates, we collect a number of other supporting data points.
Location Updates are the GPS Coordinates that are collected along with other data points that aid with the quality of the tracking. A location update is defined by Roam as a collection of the following data points.
Location updates collected by the SDK can be consumed in three ways, at the device level directly from the SDK, or using our webhooks for real-time data and the lat gets the historical data of a user using our GET location APIs.
Explore all documentation for iOS
tracking_mode
"active"
Roam's tracking mode (active
, balanced
, passive
or custom
) that was set in the SDK when the location was collected
coordinates
77.61679076999997, 12.900112149999995
Longitude, Latitude
speed
5
Speed in kilometers per hour (only during "moving"
activity)
altitude
892.7507934570312
Height above the sea level in meters
course
-1
Direction heading in relation to north
horizontal_accuracy
17.071232461095033
Horizontal accuracy of the coordinates
vertical_accuracy
20.604103088378906
Vertical accuracy of the coordinates
activity
"moving"
Whether the location update was recorded when the user was "moving"
or "stationary"
app_context
"foreground"
Wether the app was open or in the background while the location was recorded at. App States are "foreground"
, "background"
or "terminated"
tz_offset
"+0530"
Timezone where the location was recorded
battery_status
"unplugged"
Wheter the phone was "charging"
or "unplugged"
when the location was recorded
battery_remaining
51
Remaining battery in percentage of device
battery_saver
false
Is battery saver mode enabled on the device
network_status
true
Wheter internet connection is enabled or not
location_permission
true
Wheter location permission is enabled or not
id
"62f2dbd90000c6975aa8f09a"
Unique indentified for the location update
created_at
"2022-08-09T22:12:41.586"
Timestamp of the location update registered in the roam backend database at in UTC (Coordinated Universal Time)
recorded_at
"2022-08-09T22:12:45.796"
Timestamp of the location update recorded by the device in UTC (Coordinated Universal Time)
This API will provide a list of insights with boundary coordinates of the location, last visit details, type and confidence for POIs frequently visited by the user.
GET
https://api.roam.ai/v1/api/insights/poi/
user_id
string
Get POIs for the user. E.g.- 5d9450ace47bae6d70064a9b
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
{
"status": true,
"msg": "Success.",
"code": 200,
"data": {
"user_id": "5f30d339b36114713d8b610e",
"app_id": "5ed0e627372279444054d310_2",
"insights": [
{
"id": "5f3fa9c6b361144e2fbb9500",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
4.909168389987688,
52.3609200524679
],
...
...
[
4.909486939963033,
52.360889240887005
]
]
]
},
"last_visited": {
"id": "5f350a1a23c368e44d9a4854",
"coordinates": {
"type": "Point",
"coordinates": [
4.909168389987687,
52.36029052734375
]
},
"accuracy": null,
"altitude": -1.8016777038574219,
"recorded_at": "2021-06-13T09:38:27.361",
"started_at": null,
"created_at": "2021-06-13T09:38:34.169"
},
"tz_offset": "+0200",
"confidence": "Medium",
"type": "road",
"created_at": "2021-06-21T11:02:28.865"
},
{
"id": "5f3fa9c6b361144e2fbb9501",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
4.893461598938197,
52.35548792356163
],
[
4.893780109757986,
52.35545711198083
],
...
...
[
4.894067441293753,
52.355367693412276
]
]
]
},
"last_visited": {
"id": "5f3bc1fa118fe82b1a623744",
"coordinates": {
"type": "Point",
"coordinates": [
4.893461598938197,
52.3548583984375
]
},
"accuracy": null,
"altitude": -2.023803234100342,
"recorded_at": "2021-06-16T16:23:16.131",
"started_at": null,
"created_at": "2021-06-18T11:56:42.142"
},
"tz_offset": "+0200",
"confidence": "Medium",
"type": "residential",
"created_at": "2021-06-21T11:02:29.710"
},
{
"id": "5f3fa9c6b361144e2fbb9502",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
4.891453618793093,
52.35234461301476
],
...
...
[
4.891772106961156,
52.35231380143401
]
]
]
},
"last_visited": {
"id": "5f38f7a9113938bc6862e138",
"coordinates": {
"type": "Point",
"coordinates": [
4.891453618793093,
52.351715087890625
]
},
"accuracy": null,
"altitude": 1.5472954213619232,
"recorded_at": "2021-06-16T09:08:57.303",
"started_at": null,
"created_at": "2021-06-16T09:08:57.513"
},
"tz_offset": "+0200",
"confidence": "Medium",
"type": "house_number",
"created_at": "2021-06-21T11:02:30.202"
}
]
}
}
curl --location --request GET 'https://api.roam.ai/v1/api/insights/poi/?user_id=5f30d339b36114713d8b610e' \
--header 'Api-key: ee5b950fdf284474a8727409cd12bb3b'
Explore how to pause a trip with our Trip API
POST
https://api.roam.ai/v2/trips/:id/controls
Pauses the trip for the given id.
id*
String
Controls the trip with the given ID.
Authorization*
String
Bearer <API-KEY>
user_id*
String
The user for which the trip is being tracked.
paused_at*
String
Timestamp is UTC for action:pause eg: 2022-01-14T09:10:59.125
action*
String
To control the trip.
eg. start, pause, resume, end
{
"code": 201,
"message": "trip_paused",
"description": "The trip is paused successfully.",
"trip": {
"id": "62132b22f13667633fbad210",
"name": "Test Delivery",
"description": "item pickup for test users",
"trip_state": "paused",
"total_distance": 0,
"total_duration": 0,
"total_elevation_gain": 0,
"metadata": {
"_id": 21,
"order_id": "1123"
},
"start_location": {},
"end_location": {},
"user": {
"id": "61ffb486d2c69840ee518073",
"name": "",
"description": "1200",
"metadata": {
"Mobile": "1234567890",
"Name": "Nikhil"
}
},
"started_at": "2022-02-21T06:03:15.649",
"ended_at": null,
"created_at": "2022-02-21T06:03:14.650",
"updated_at": "2022-02-21T06:09:16.988",
"events": [
{
"id": "62132b28c78454e82f29a5f1",
"trip_id": "62132b22f13667633fbad210",
"location_id": "",
"user_id": "61ffb486d2c69840ee518073",
"event_type": "roam:trip:created",
"created_at": "2022-02-21T06:03:20.603",
"event_source": "roam:trip",
"event_version": "2.0"
},
{
"id": "62132c93e146f0fe9be367cb",
"trip_id": "62132b22f13667633fbad210",
"location_id": "61f3c437a747ba00000915cf",
"user_id": "61ffb486d2c69840ee518073",
"event_type": "roam:trip:started",
"created_at": "2022-02-21T06:09:22.418",
"event_source": "roam:trip",
"event_version": "2.0"
}
],
"stops": [
{
"id": "62132b22f13667633fbad20e",
"name": "Delivery",
"description": "test Pickup for Johan",
"metadata": {
"order_id": "1120"
},
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
},
"created_at": "2022-02-21T06:03:14.607",
"updated_at": "2022-02-21T06:03:14.607",
"arrived_at": null,
"departed_at": null
},
{
"id": "62132b22f13667633fbad20f",
"name": "Delivery",
"description": "another tester Pickup for Johan",
"metadata": {
"order_id": "1129"
},
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
},
"created_at": "2022-02-21T06:03:14.649",
"updated_at": "2022-02-21T06:03:14.649",
"arrived_at": null,
"departed_at": null
}
]
}
}
{
"code" : 400,
"message" : "invalid_request_error",
"description": "The request was unacceptable, due to missing a required parameter or invalid parameter.",
"errors" : [
{
"field" : "user_id",
"message" : "This field should be a valid user id"
},
{
"field" : "stops.id",
"message" : "This field should be a valid stop id"
},
{
"field" : "stops.geometry_radius",
"message" : "This field should be valid number between 10 and 10000"
}
]
}
curl --location --request POST 'https://api.roam.ai/v2/trips/62132b22f13667633fbad210/controls' \
--header 'Authorization: Bearer dfbbf5d5ff6b41ecb1166147b87c0544' \
--header 'Content-Type: application/json' \
--data-raw '{
"user_id":"61ffb486d2c69840ee518073",
"paused_at":"2022-02-21T06:03:15.649",
"action": "pause"
}'
Explore how to pause a trip on Android with Trips v2.
The pause trip method allows you to pause the trip with the previously created tripID.
Roam.pauseTrip("tripId", new RoamTripCallback() {
@Override
public void onSuccess(RoamTripResponse response) {
//get trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
Roam.pauseTrip("tripId", object : RoamTripCallback {
override fun onSuccess(response: RoamTripResponse) {
//get trip details
}
override fun onError(error: Error?) {
//get error details
}
})
The trip response and its parameters are similar to those of the createTrip method.
Explore all of Roam's iOS SDK methods.
id*
String
Controls the trip with the given ID.
Authorization*
String
Bearer <API-KEY>
user_id*
String
The user for which the trip is being tracked.
resumed_at*
String
Timestamp is UTC for action:resume eg: 2022-01-14T09:10:59.125
action*
String
To control the trip.
eg. start, pause, resume, end
{
"code" : 400,
"message" : "invalid_request_error",
"description": "The request was unacceptable, due to missing a required parameter or invalid parameter.",
"errors" : [
{
"field" : "user_id",
"message" : "This field should be a valid user id"
},
{
"field" : "stops.id",
"message" : "This field should be a valid stop id"
},
{
"field" : "stops.geometry_radius",
"message" : "This field should be valid number between 10 and 10000"
}
]
}
curl --location --request POST 'https://api.roam.ai/v2/trips/62132b22f13667633fbad210/controls' \
--header 'Authorization: Bearer dfbbf5d5ff6b41ecb1166147b87c0544' \
--header 'Content-Type: application/json' \
--data-raw '{
"user_id":"61ffb486d2c69840ee518073",
"resumed_at":"2022-02-21T06:03:15.649",
"action": "resume"
}'
{
"code": 201,
"message": "trip_resumed",
"description": "The trip is resumed successfully.",
"trip": {
"id": "62132b22f13667633fbad210",
"name": "Test Delivery",
"description": "item pickup for test users",
"trip_state": "resumed",
"total_distance": 0,
"total_duration": 0,
"total_elevation_gain": 0,
"metadata": {
"_id": 21,
"order_id": "1123"
},
"start_location": {},
"end_location": {},
"user": {
"id": "61ffb486d2c69840ee518073",
"name": "",
"description": "1200",
"metadata": {
"Mobile": "1234567890",
"Name": "Nikhil"
}
},
"started_at": "2022-02-21T06:03:15.649",
"ended_at": null,
"created_at": "2022-02-21T06:03:14.650",
"updated_at": "2022-02-21T06:14:11.061",
"events": [
{
"id": "62132b28c78454e82f29a5f1",
"trip_id": "62132b22f13667633fbad210",
"location_id": "",
"user_id": "61ffb486d2c69840ee518073",
"event_type": "roam:trip:created",
"created_at": "2022-02-21T06:03:20.603",
"event_source": "roam:trip",
"event_version": "2.0"
},
{
"id": "62132c93e146f0fe9be367cb",
"trip_id": "62132b22f13667633fbad210",
"location_id": "61f3c437a747ba00000915cf",
"user_id": "61ffb486d2c69840ee518073",
"event_type": "roam:trip:started",
"created_at": "2022-02-21T06:09:22.418",
"event_source": "roam:trip",
"event_version": "2.0"
},
{
"id": "62132db5e146f0fe9be367cc",
"trip_id": "62132b22f13667633fbad210",
"location_id": "61f3c437a747ba00000915cf",
"user_id": "61ffb486d2c69840ee518073",
"event_type": "roam:trip:paused",
"created_at": "2022-02-21T06:14:13.626",
"event_source": "roam:trip",
"event_version": "2.0"
}
],
"stops": [
{
"id": "62132b22f13667633fbad20e",
"name": "Delivery",
"description": "test Pickup for Johan",
"metadata": {
"order_id": "1120"
},
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
},
"created_at": "2022-02-21T06:03:14.607",
"updated_at": "2022-02-21T06:03:14.607",
"arrived_at": null,
"departed_at": null
},
{
"id": "62132b22f13667633fbad20f",
"name": "Delivery",
"description": "another tester Pickup for Johan",
"metadata": {
"order_id": "1129"
},
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
},
"created_at": "2022-02-21T06:03:14.649",
"updated_at": "2022-02-21T06:03:14.649",
"arrived_at": null,
"departed_at": null
}
]
}
}
id*
String
Exports the trip summary with the given ID.
format*
String
Export type as csv/gpx/json/geojson
eg: gpx
Authorization*
String
Bearer <API-KEY>
curl --location --request GET 'https://api.roam.ai/v2/trips/620f4fb7d79b3200007cd92c/export?format=gpx' \
--header 'Authorization: Bearer dfbbf5d5XXXXcb1166147b87c0544'
{
"code":200,
"message":"trip_export_finished",
"description":"The trip data is exported successfully for requested id.",
"data": {
"trip_id": "61dec6e206f8a019b2402c0b",
"download_url": "https://roam-gpx-files.s3.amazonaws.com/61dec6e206f8a019b2402c0b.gpx"
}
}
{
"code" : 404,
"message" : "object_not_found",
"description": "The requested object does not exist or already deleted.",
"errors" : [ ]
}
Explore how to start a quick trip on Android with Trips v2.
A Quick Trip creates and starts a trip immediately with a single method. Creating a quick trip is similar to creating a trip.
metadata
JSONObject
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
tripName
String
Name of the trip
tripDescription
String
Trip description
isLocal
boolean
Value determining if the trip is a local trip.
Along with the above trip object, you need to pass an additional parameter for trackingMode
which is optional and defaults to active tracking mode.
Roam.startTrip(trip, RoamTrackingMode.active, new RoamTripCallback() {
@Override
public void onSuccess(RoamTripResponse response) {
//get trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
Roam.startTrip(trip, RoamTrackingMode.ACTIVE, object : RoamTripCallback {
override fun onSuccess(response: RoamTripResponse) {
//get trip details
}
override fun onError(error: Error?) {
//get error details
}
})
To start a quick trip in custom tracking mode, refer to the following code snippet block.
RoamTrackingMode roamTrackingMode = new RoamTrackingMode.Builder(distanceFilter, stopDuration)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build();
Roam.startTrip(trip, roamTrackingMode, new RoamTripCallback() {
@Override
public void onSuccess(RoamTripResponse response) {
//get trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
val roamTrackingMode = RoamTrackingMode.Builder(distanceFilter, stopDuration)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build()
Roam.startTrip(trip, roamTrackingMode, object : RoamTripCallback {
override fun onSuccess(response: RoamTripResponse) {
//get trip details
}
override fun onError(error: Error?) {
//get error details
}
})
The list of responses and error parameters are given below with their descriptions.
To access the status parameters:
response.getCode()
Integer
The response code of the method.
response.getMessage()
String
The response message of the method.
To access trip responses:
getTripDetails().getTripId()
String
Unique identifier for the object.
getTripDetails().getMetadata()
Object
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
getTripDetails().getTripName()
String
The trip name
getTripDetails().getTripDescription()
String
The trip’s description
getTripDetails().getTripState()
String
The current state of the trip is either created, started, or ended.
getTripDetails().getIsLocal()
boolean
The value determining if the trip is a local trip.
getTripDetails().getTotalDistance()
double
The total distance covered by the user for this trip.
getTripDetails().getTotalDuration()
double
The total duration taken by the user for this trip.
getTripDetails().getTotalElevationGain()
double
The total elevation gain covered by the user for this trip.
getTripDetails().createdAt()
String
Timestamp of when the trip was created
getTripDetails().updatedAt()
String
Timestamp of when the trip was updated
getTripDetails().startedAt()
String
Timestamp of when the trip was started by the user
getTripDetails().endedAt()
String
Timestamp of when the trip was ended by the user
To access user details:
getUser().getId()
String
Unique identifier for the object.
getUser().getMetadata()
Object
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
getUser().getDescription()
String
User description
getUser().getName()
String
The user's full name
To access error details:
error.getErrorCode()
Integer
The error response code of the method.
error.getErrorMessage()
String
Error response message of the method.
error.getErrorDescription()
String
Error response description of the method.
error.getErrors().get(i).getMessage()
String
Message for error detail.
error.getErrors.get(i).getField()
String
The field for error detail.
Explore how to update a trip with our Trip API
PUT
https://api.roam.ai/v2/trips/:id
Updates the metadata, description and name of a trip. Details of existing stop locations like metadata, description, name and address can be updated except geometry_radius and geometry by passing stop location id. To add new stop location, add new stop location item to array without id. To remove the existing stop location, remove the entire item in the array which will remove the stop location only if it is not entered/existed by the assigned user.
You cannot update the user once the trip is started.
id*
String
Updates the trip with the given ID.
Authorization*
String
Bearer <API-KEY>
user_id
String
The user for which the trip is being tracked.
description
String
Description of the trip. By default the id is shown if the description is not set.
name
String
Name of the trip. By default the id is shown if the name is not set.
metadata
Dictionary
Set of key-value pairs that you can attach to the trip. This can be useful for storing additional information about the trip in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to metadata.
stops
Array
For the trips with stop locations, add an array of stop locations.
stops.metadata
Dictionary
Set of key-value pairs that you can attach to the stop location. This can be useful for storing additional information about the stop location in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to metadata.
stops.name
String
Name of the stop location. By default the id is shown if the name is not set.
stops.description
String
Description of the stop location. By default the id is shown if the description is not set.
stops.address
String
Address of the stop location.
stops.geometry_radius
Number
The radius in meters.
stops.geometry
Point
Location coordinates in GeoJSON format.
{
"code": 201,
"message": "trip_updated",
"description": "The trip data is updated successfully for given id.",
"trip": {
"id": "620f26ad9ba7360496bc1be7",
"name": "Test Delivery",
"description": "item pickup for test users",
"trip_state": "created",
"total_distance": 0,
"total_duration": 0,
"total_elevation_gain": 0,
"metadata": {
"_id": 21,
"order_id": "1123"
},
"start_location": {},
"end_location": {},
"user": {
"id": "61ffb486d2c69840ee518073",
"name": "",
"description": "1200",
"metadata": {
"Mobile": "1234567890",
"Name": "Nikhil"
}
},
"started_at": null,
"ended_at": null,
"created_at": "2022-02-18T04:55:09.660",
"updated_at": "2022-02-18T04:55:09.660",
"events": [],
"stops": [
{
"id": "620f26ad9ba7360496bc1be5",
"name": "Delivery",
"description": "test Pickup for Johan",
"metadata": {
"order_id": "1120"
},
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
},
"created_at": "2022-02-18T04:55:09.658",
"updated_at": "2022-02-18T04:55:09.658",
"arrived_at": null,
"departed_at": null
},
{
"id": "620f26ad9ba7360496bc1be6",
"name": "Delivery",
"description": "another tester Pickup for Johan",
"metadata": {
"order_id": "1129"
},
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
},
"created_at": "2022-02-18T04:55:09.659",
"updated_at": "2022-02-18T04:55:09.659",
"arrived_at": null,
"departed_at": null
}
]
}
}
{
"code" : 400,
"message" : "invalid_request_error",
"description": "The request was unacceptable, due to missing a required parameter or invalid parameter.",
"errors" : [
{
"field" : "user_id",
"message" : "This field should be a valid user id"
},
{
"field" : "stops.id",
"message" : "This field should be a valid stop id"
},
{
"field" : "stops.geometry_radius",
"message" : "This field should be valid number between 10 and 10000"
}
]
}
curl --location --request POST 'https://api.roam.ai/v2/trips' \
--header 'Authorization: Bearer dfbbf5d5ff6b41ecb1166147b87c0544' \
--header 'Content-Type: application/json' \
--data-raw '{
"user_id": "61ffb486d2c69840ee518073",
"description": "item pickup for test users",
"name": "Test Delivery",
"metadata": {
"order_id": "1123",
"_id": 21
},
"stops": [
{
"metadata": {"order_id": "1120"},
"description": "test Pickup for Johan",
"name": "Delivery",
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
}
},
{
"metadata": {"order_id": "1129"},
"description": "another tester Pickup for Johan",
"name": "Delivery",
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
}
}
]
}'
Explore how to start a trip with our Trip API
POST
https://api.roam.ai/v2/trips/:id/controls
Starts the trip for the given id.
id*
String
Controls the trip with the given ID.
Authorization*
String
Bearer <API-KEY>
user_id*
String
The user for which the trip is being tracked.
started_at*
String
Timestamp is UTC for action:start eg: 2022-01-14T09:10:59.125
action*
String
To control the trip.
eg. start, pause, resume, end
{
"code": 201,
"message": "trip_started",
"description": "The trip is started successfully.",
"trip": {
"id": "62132b22f13667633fbad210",
"name": "Test Delivery",
"description": "item pickup for test users",
"trip_state": "started",
"total_distance": 0,
"total_duration": 0,
"total_elevation_gain": 0,
"metadata": {
"_id": 21,
"order_id": "1123"
},
"start_location": {},
"end_location": {},
"user": {
"id": "61ffb486d2c69840ee518073",
"name": "",
"description": "1200",
"metadata": {
"Mobile": "1234567890",
"Name": "Nikhil"
}
},
"started_at": null,
"ended_at": null,
"created_at": "2022-02-21T06:03:14.650",
"updated_at": "2022-02-21T06:03:14.650",
"events": [
{
"id": "62132b28c78454e82f29a5f1",
"trip_id": "62132b22f13667633fbad210",
"location_id": "",
"user_id": "61ffb486d2c69840ee518073",
"event_type": "roam:trip:created",
"created_at": "2022-02-21T06:03:20.603",
"event_source": "roam:trip",
"event_version": "2.0"
}
],
"stops": [
{
"id": "62132b22f13667633fbad20e",
"name": "Delivery",
"description": "test Pickup for Johan",
"metadata": {
"order_id": "1120"
},
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
},
"created_at": "2022-02-21T06:03:14.607",
"updated_at": "2022-02-21T06:03:14.607",
"arrived_at": null,
"departed_at": null
},
{
"id": "62132b22f13667633fbad20f",
"name": "Delivery",
"description": "another tester Pickup for Johan",
"metadata": {
"order_id": "1129"
},
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
},
"created_at": "2022-02-21T06:03:14.649",
"updated_at": "2022-02-21T06:03:14.649",
"arrived_at": null,
"departed_at": null
}
]
}
}
{
"code" : 400,
"message" : "invalid_request_error",
"description": "The request was unacceptable, due to missing a required parameter or invalid parameter.",
"errors" : [
{
"field" : "user_id",
"message" : "This field should be a valid user id"
}
]
}
curl --location --request POST 'https://api.roam.ai/v2/trips/62132b22f13667633fbad210/controls' \
--header 'Authorization: Bearer dfbbf5d5ff6b41ecb1166147b87c0544' \
--header 'Content-Type: application/json' \
--data-raw '{
"user_id":"61ffb486d2c69840ee518073",
"started_at":"2022-02-21T06:03:15.649",
"action": "start"
}'
Explore how to end a trip with our Trip API
POST
https://api.roam.ai/v2/trips/:id/controls
Ends the trip for the given id.
id*
String
Controls the trip with the given ID.
Authorization*
String
Bearer <API-KEY>
user_id*
String
The user for which the trip is being tracked.
ended_at*
String
Timestamp is UTC for action:resume eg: 2022-01-14T09:10:59.125
action*
String
To control the trip.
eg. start, pause, resume, end
{
"code": 201,
"message": "trip_resumed",
"description": "The trip is resumed successfully.",
"trip": {
"id": "62132b22f13667633fbad210",
"name": "Test Delivery",
"description": "item pickup for test users",
"trip_state": "resumed",
"total_distance": 0,
"total_duration": 0,
"total_elevation_gain": 0,
"metadata": {
"_id": 21,
"order_id": "1123"
},
"start_location": {},
"end_location": {},
"user": {
"id": "61ffb486d2c69840ee518073",
"name": "",
"description": "1200",
"metadata": {
"Mobile": "1234567890",
"Name": "Nikhil"
}
},
"started_at": "2022-02-21T06:03:15.649",
"ended_at": null,
"created_at": "2022-02-21T06:03:14.650",
"updated_at": "2022-02-21T06:14:11.061",
"events": [
{
"id": "62132b28c78454e82f29a5f1",
"trip_id": "62132b22f13667633fbad210",
"location_id": "",
"user_id": "61ffb486d2c69840ee518073",
"event_type": "roam:trip:created",
"created_at": "2022-02-21T06:03:20.603",
"event_source": "roam:trip",
"event_version": "2.0"
},
{
"id": "62132c93e146f0fe9be367cb",
"trip_id": "62132b22f13667633fbad210",
"location_id": "61f3c437a747ba00000915cf",
"user_id": "61ffb486d2c69840ee518073",
"event_type": "roam:trip:started",
"created_at": "2022-02-21T06:09:22.418",
"event_source": "roam:trip",
"event_version": "2.0"
},
{
"id": "62132db5e146f0fe9be367cc",
"trip_id": "62132b22f13667633fbad210",
"location_id": "61f3c437a747ba00000915cf",
"user_id": "61ffb486d2c69840ee518073",
"event_type": "roam:trip:paused",
"created_at": "2022-02-21T06:14:13.626",
"event_source": "roam:trip",
"event_version": "2.0"
}
],
"stops": [
{
"id": "62132b22f13667633fbad20e",
"name": "Delivery",
"description": "test Pickup for Johan",
"metadata": {
"order_id": "1120"
},
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
},
"created_at": "2022-02-21T06:03:14.607",
"updated_at": "2022-02-21T06:03:14.607",
"arrived_at": null,
"departed_at": null
},
{
"id": "62132b22f13667633fbad20f",
"name": "Delivery",
"description": "another tester Pickup for Johan",
"metadata": {
"order_id": "1129"
},
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
},
"created_at": "2022-02-21T06:03:14.649",
"updated_at": "2022-02-21T06:03:14.649",
"arrived_at": null,
"departed_at": null
}
]
}
}
{
"code" : 400,
"message" : "invalid_request_error",
"description": "The request was unacceptable, due to missing a required parameter or invalid parameter.",
"errors" : [
{
"field" : "user_id",
"message" : "This field should be a valid user id"
},
{
"field" : "stops.id",
"message" : "This field should be a valid stop id"
},
{
"field" : "stops.geometry_radius",
"message" : "This field should be valid number between 10 and 10000"
}
]
}
curl --location --request POST 'https://api.roam.ai/v2/trips/62132b22f13667633fbad210/controls' \
--header 'Authorization: Bearer dfbbf5d5ff6b41ecb1166147b87c0544' \
--header 'Content-Type: application/json' \
--data-raw '{
"user_id":"61ffb486d2c69840ee518073",
"ended_at":"2022-02-21T06:03:15.649",
"action": "end"
}'
The Create Trip API helps you to create a new trip with an origin, destination, and user.
POST
https://api.roam.ai/v1/api/trips/
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
user_id
string
User-id for which the trip needs to be assigned E.g.- 5d9450ace47bae6d70064a9b
origins
array
Single or multiple origin locations in [long, lat] format. E.g.- [[77.677270, 12.914131]]
destinations
array
Single or multiple destination locations in [long, lat] format. E.g.- [[77.700475, 12.957005]]
{
"status": true,
"msg": "Success.",
"code": 201,
"data": [
{
"id": "<ID>",
"origins": [
{
"id": "<ID>",
"trip_id": "<TRIP-ID>",
"created_at": "2020-09-22T06:00:34.264",
"updated_at": "2020-09-22T06:00:34.269",
"coordinates": {
"type": "Point",
"coordinates": [
77.622977,
12.917042
]
},
"loc_type": "origin"
}
],
"destinations": [
{
"id": "<ID>",
"trip_id": "<TRIP-ID>",
"created_at": "2020-09-22T06:00:34.272",
"updated_at": "2020-09-22T06:00:34.275",
"coordinates": {
"type": "Point",
"coordinates": [
77.650239,
12.924304
]
},
"loc_type": "destination"
},
{
"id": "<ID>",
"trip_id": "<TRIP-ID>",
"created_at": "2020-09-22T06:00:34.278",
"updated_at": "2020-09-22T06:00:34.281",
"coordinates": {
"type": "Point",
"coordinates": [
77.697418,
12.959172
]
},
"loc_type": "destination"
}
],
"events": [],
"user_id": "<USER-ID>",
"is_started": false,
"is_ended": false,
"is_deleted": false,
"created_at": "2021-06-22T06:00:34.261",
"updated_at": "2021-06-22T06:00:34.261",
"trip_tracking_url": "https://trips.gs/NWY2OTkzMDI5NzI0MjIwNThmY2ZjYTFlfHNmZHNnZHNh"
}
]
}
curl --location --request POST 'https://api.roam.ai/v1/api/trips/' \
--header 'Api-key: <API-KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"user_id": "<USER-ID>",
"origins": [[77.622977 ,12.917042]],
"destinations":[[77.650239 ,12.924304], [77.697418 ,12.959172]]
}'
Explore the iOS SDK Methods for Trip API v1. Check out the latest methods if you are using Trips API v2!
The SDK can start a quick trip with a single function which accepts optional values for tracking modes, origin and destinations.
You can now stop the trip and control the tracking modes directly from the stop trip method. This allows you to either force stop location tracking or change the tracking mode using the stop trip method.
You can also use the below methods to manually create a trip and then use the tripID to start the trip.
Use the code below to create a trip directly from the SDK. Set the Boolean value to true
to create an offline trip and false
to create an online trip.
Start trip starts the trip with the previously created tripID.
Pause trip pauses a previously started trip with its tripID.
Resume trip resumes a previously paused trip.
Subscribe to tripStatus
using the tripId
to get real-time trip status.
To stop receiving trip status updates, use the method below.
The Get Events API lets you fetch the entry or exit events of the users from your event enabled geofences. The API also lets you filter by user or geofence, location, and more.
Roam.createTrip(Bool, nil) { (roamTrip, roamError) in
// access roam trip created timestamp with roamTrip?.createdAt
// access roam trip user id with roamTrip?.userId
// access roam trip id with roamTrip?.tripId
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}
[Roam createTrip:true :nil handler:^(RoamCreateTrip * roamTrip, RoamError * roamError) {
// access roam trip created timestamp with roamTrip?.createdAt
// access roam trip user id with roamTrip?.userId
// access roam trip id with roamTrip?.tripId
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}];
Roam.getTripDetails("ROAM-TRIP-ID") { (roamTrip, roamError) in
// access roam trip created timestamp with roamTrip?.createdAt
// access roam trip user id with roamTrip?.userId
// access roam trip id with roamTrip?.tripId
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}
[Roam getTripDetails:@"ROAM-TRIP-ID" handler:^(RoamGetTrip * roamTrip, RoamError * roamError) {
// access roam trip created timestamp with roamTrip?.createdAt
// access roam trip user id with roamTrip?.userId
// access roam trip id with roamTrip?.tripId
// access roam error code with roamTrip?.code
// access roam error message with roamError?.message
}];
Roam.startTrip("ROAM-TRIP-ID") { (status, roamError) in
// access roam trip status with status
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}
[Roam startTrip:@"ROAM-TRIP-ID" :@"ROAM-TRIP-DESC" handler:^(NSString * status, RoamError * roamError) {
// access roam trip status with status
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}];
Roam.stopTrip("ROAM-TRIP-ID") { (status, roamError) in
// access roam trip status with status
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}
[Roam stopTrip:@"ROAM-TRIP-ID" handler:^(NSString * status, RoamError * roamError) {
// access roam trip status with status
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}];
Roam.pauseTrip("ROAM-TRIP-ID") { (status, error) in
// access roam trip status with status
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}
[Roam pauseTrip:@"ROAM-TRIP-ID" handler:^(NSString * status, RoamError * roamError) {
// access roam trip status with status
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}];
Roam.resumeTrip("ROAM-TRIP-ID") { (status, roamError) in
// access roam trip status with status
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}
[Roam resumeTrip:@"ROAM-TRIP-ID" handler:^(NSString * status, RoamError * roamError) {
// access roam trip status with status
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}];
//subscribe to trip status
Roam.subscribeTripStatus("ROAM-TRIP-ID")
//subscribe to trip status
[Roam subscribeTripStatus:@"ROAM-TRIP-ID")
// unsubscribe from all the trip
Roam.unsubscribeTripStatus()
// unsubscribe from trip
Roam.unsubscribeTripStatus('ROAM-TRIP-ID')
// unsubscribe from all the trip
[Roam unsubscribeTripStatus:NULL];
// unsubscribe from trip
[Roam unsubscribeTripStatus:@"ROAM-TRIP-ID"];
Roam.getTripStatus("ROAM-TRIP-ID") { (roamTrip, roamError) in
// access roam trip distance covered with roamTrip?.distance
// access roam trip speed with roamTrip?.speed
// access roam trip duration with roamTrip?.duration
// access roam trip id with roamTrip?.tripId
// access roam trip started timestamp with roamTrip?.startedAt
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}
[Roam getTripStatus:@"ROAM-TRIP-ID" handler:^(RoamTripListener * roamTrip, RoamError * roamError) {
// access roam trip distance covered with roamTrip?.distance
// access roam trip speed with roamTrip?.speed
// access roam trip duration with roamTrip?.duration
// access roam trip id with roamTrip?.tripId
// access roam trip started timestamp with roamTrip?.startedAt
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}];
Roam.getTripSummary("ROAM-TRIP-ID") { (roamTrip, roamError) in
// access roam trip distance covered with roamTrip?.distanceCovered
// access roam trip route with roamTrip?.route
// access roam trip duration with roamTrip?.duration
// access roam trip id with roamTrip?.tripId
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}
[Roam getTripSummary:@"ROAM-TRIP-ID" handler:^(RoamTripSummary * roamTrip, RoamError * roamError) {
// access roam trip distance covered with roamTrip?.distanceCovered
// access roam trip route with roamTrip?.route
// access roam trip duration with roamTrip?.duration
// access roam trip id with roamTrip?.tripId
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}];
// tripId as String
// localTrip as Bool
// RoamTrackingMode
// tripDescription as string
// origin as Array<Array<Double>> [[latitude,longitude],[latitude,longitude]]
// destination as Array<Array<Double>> [[latitude,longitude],[latitude,longitude]]
// option for custom tracking RoamTrackingCustomMethods
[Roam startTrip:@"tripId" :BOOL :RoamTrackingModeActive :@"tripDescription" :origins :destination :RoamTrackingCustomMethods handler:^(RoamStartTrip * startTrip, RoamError * error) {
}];
[Roam stopTrip:@"" forceStopTracking:false :RoamTrackingModeActive :RoamTrackingCustomMethods handler:^(NSString * status, RoamError * error) {
}];
// tripId as String
// localTrip as Bool
// RoamTrackingMode
// tripDescription as string
// origin as Array<Array<Double>> [[latitude,longitude],[latitude,longitude]]
// destination as Array<Array<Double>> [[latitude,longitude],[latitude,longitude]]
// option for custom tracking RoamTrackingCustomMethods
Roam.startTrip("tripId", false, RoamTrackingMode.active, "tripDescription", origins, destination ) { startTrip, error in
// access roam trip created timestamp with roamTrip?.createdAt
// access roam trip user id with roamTrip?.userId
// access roam trip id with roamTrip?.tripId
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}
// tripId as String
// forceStopTracking as Bool
// RoamTrackingMode
// option for custom tracking RoamTrackingCustomMethods
Roam.stopTrip("tripId", forceStopTracking: true, RoamTrackingMode, RoamTrackingCustomMethods) { roamStatus, roamError in
// access trip status with roamStatus
// access roam error code with roamError?.code
// access roam error message with roamError?.message
}
Authorization*
String
Bearer <API-KEY>
user_id
String
The user for which the trip is being tracked.
description
String
Description of the trip. By default the id is shown if the description is not set.
name
String
Name of the trip. By default the id is shown if the name is not set.
metadata
Dictionary
Set of key-value pairs that you can attach to the trip. This can be useful for storing additional information about the trip in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to metadata.
stops
Array
For the trips with stop locations, add an array of stop locations.
stops.metadata
Dictionary
Set of key-value pairs that you can attach to the stop location. This can be useful for storing additional information about the stop location in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to metadata.
stops.name
String
Name of the stop location. By default the id is shown if the name is not set.
stops.description
String
Description of the stop location. By default the id is shown if the description is not set.
stops.address
String
Address of the stop location.
stops.geometry_radius
Number
The radius in meters.
stops.geometry
Point
Location coordinates in GeoJSON format.
{
"code" : 400,
"message" : "invalid_request_error",
"description": "The request was unacceptable, due to missing a required parameter or invalid parameter.",
"errors" : [
{
"field" : "user_id",
"message" : "This field should be a valid user id"
},
{
"field" : "stops.geometry",
"message" : "This field should be valid GeoJSON"
},
{
"field" : "stops.geometry_radius",
"message" : "This field should be valid number between 10 and 10000"
}
]
}
curl --location --request POST 'https://api.roam.ai/v2/trips' \
--header 'Authorization: Bearer dfbbf5d5ff6b41ecb1166147b87c0544' \
--header 'Content-Type: application/json' \
--data-raw '{
"user_id": "61ffb486d2c69840ee518073",
"description": "item pickup for test users",
"name": "Test Delivery",
"metadata": {
"order_id": "1123",
"_id": 21
},
"stops": [
{
"metadata": {"order_id": "1120"},
"description": "test Pickup for Johan",
"name": "Delivery",
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
}
},
{
"metadata": {"order_id": "1129"},
"description": "another tester Pickup for Johan",
"name": "Delivery",
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
}
}
]
}'
{
"code": 201,
"message": "trip_created",
"description": "The trip is created successfully.",
"trip": {
"id": "620f26ad9ba7360496bc1be7",
"name": "Test Delivery",
"description": "item pickup for test users",
"trip_state": "created",
"total_distance": 0,
"total_duration": 0,
"total_elevation_gain": 0,
"metadata": {
"_id": 21,
"order_id": "1123"
},
"start_location": {},
"end_location": {},
"user": {
"id": "61ffb486d2c69840ee518073",
"name": "",
"description": "1200",
"metadata": {
"Mobile": "1234567890",
"Name": "Nikhil"
}
},
"started_at": null,
"ended_at": null,
"created_at": "2022-02-18T04:55:09.660",
"updated_at": "2022-02-18T04:55:09.660",
"events": [],
"stops": [
{
"id": "620f26ad9ba7360496bc1be5",
"name": "Delivery",
"description": "test Pickup for Johan",
"metadata": {
"order_id": "1120"
},
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
},
"created_at": "2022-02-18T04:55:09.658",
"updated_at": "2022-02-18T04:55:09.658",
"arrived_at": null,
"departed_at": null
},
{
"id": "620f26ad9ba7360496bc1be6",
"name": "Delivery",
"description": "another tester Pickup for Johan",
"metadata": {
"order_id": "1129"
},
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
},
"created_at": "2022-02-18T04:55:09.659",
"updated_at": "2022-02-18T04:55:09.659",
"arrived_at": null,
"departed_at": null
}
]
}
}
user_id
string
Filters events data for the given user_id. E.g.- 5d9450ace47bae6d70064a9b
geofence_id
string
Filters events data for the given geofence_id. E.g.- 5eecc7491e621663c93ba2fe
start_date
string
Filters events data for the given date range. E.g.- 2020-08-05
end_date
string
Filters events data for the given date range. E.g.- 2020-08-09
page_number
integer
This field can be used for getting 10 entries at a time. if the response returns an empty list in the data field, it is safe to assume the pages are exhausted. If the points_encoded value is true, then this value will not be considered. E.g.- 1
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
curl --location --request GET 'https://api.roam.ai/v1/api/event/?geofence_id=5eecc7491e621663c93ba2fe&start_date=2020-08-05&end_date=2020-08-09&page_number=1&user_id=5f2bd1e9b3611421f252e36c' \
--header 'Api-Key: 50ccfe35a1ee409f9791cdee340e5864'
{
"status": true,
"msg": "Success.",
"code": 200,
"data": {
"next_page": 2,
"pages": 3,
"prev_page": null,
"account_id": "5c0179df6f994031158a5646",
"events": [
{
"id": "5f2c03c40401996e6d6c8ad4",
"user_description": "postman device test",
"user_id": "5f2be41bb3611421f252e3c3",
"geofence_description": "365",
"geofence_id": "5eecc7491e621663c93ba2fe",
"location_id": "5f2be4ede3872b4e6519f8f2",
"event_type": "motion:geofence:entry",
"recorded_at": "2020-08-06T11:09:33.280",
"created_at": "2020-08-06T13:21:08.283",
"is_deleted": false
},
{
"id": "5f2be6634fac5ac31f740a09",
"user_description": "postman device test",
"user_id": "5f2be3c5b3611421f152e0dc",
"geofence_description": "365",
"geofence_id": "5eecc7491e621663c93ba2fe",
"location_id": "5f2be662e3872b4f0d138e13",
"event_type": "motion:geofence:entry",
"recorded_at": "2020-08-06T11:15:46.107",
"created_at": "2020-08-06T11:15:47.285",
"is_deleted": false
},
{
"id": "5f2be5ab972cb25c216b8bc8",
"user_description": "postman device test",
"user_id": "5f2be41bb3611421f252e3c3",
"geofence_description": "365",
"geofence_id": "5eecc7491e621663c93ba2fe",
"location_id": "5f2be4ede3872b4e6519f8f2",
"event_type": "motion:geofence:entry",
"recorded_at": "2020-08-06T11:09:33.280",
"created_at": "2020-08-06T11:12:43.542",
"is_deleted": false
},
{
"id": "5f2be4ef4fac5ac31f740a08",
"user_description": "postman device test",
"user_id": "5f2be41bb3611421f252e3c3",
"geofence_description": "365",
"geofence_id": "5eecc7491e621663c93ba2fe",
"location_id": "5f2be4ede3872b4e6519f8f2",
"event_type": "motion:geofence:entry",
"recorded_at": "2020-08-06T11:09:33.280",
"created_at": "2020-08-06T11:09:35.655",
"is_deleted": false
},
{
"id": "5f2be028ad018ed53929605a",
"user_description": "postman device test",
"user_id": "5f2bd1e9b3611421f252e36c",
"geofence_description": "365",
"geofence_id": "5eecc7491e621663c93ba2fe",
"location_id": "5f2be027e3872b4b97b61f6d",
"event_type": "motion:geofence:entry",
"recorded_at": "2020-08-06T10:49:11.381",
"created_at": "2020-08-06T10:49:12.636",
"is_deleted": false
},
{
"id": "5f2bdd15cb6a6dd83389d2fe",
"user_description": "postman device test",
"user_id": "5f2bd4cfb3611421f252e378",
"geofence_description": "365",
"geofence_id": "5eecc7491e621663c93ba2fe",
"location_id": "5f2bdd12e3872b49dc215b1f",
"event_type": "motion:geofence:entry",
"recorded_at": "2020-08-06T10:36:02.951",
"created_at": "2020-08-06T10:36:05.404",
"is_deleted": false
},
{
"id": "5f2bd913b371fa62bad8fda5",
"user_description": "postman device test",
"user_id": "5f2bd1e9b3611421f252e36c",
"geofence_description": "365",
"geofence_id": "5eecc7491e621663c93ba2fe",
"location_id": "5f2bd90fe3872b46fe340362",
"event_type": "motion:geofence:exit",
"recorded_at": "2020-08-06T10:18:55.914",
"created_at": "2020-08-06T10:18:59.112",
"is_deleted": false
},
{
"id": "5f2bd565b371fa62bad8fda2",
"user_description": "postman device test",
"user_id": "5f2bd1e9b3611421f252e36c",
"geofence_description": "365",
"geofence_id": "5eecc7491e621663c93ba2fe",
"location_id": "5f2bd562e3872b43e156a54a",
"event_type": "motion:geofence:entry",
"recorded_at": "2020-08-06T10:03:14.617",
"created_at": "2020-08-06T10:03:17.245",
"is_deleted": false
},
{
"id": "5efc696e8cb244000185ea2d",
"user_description": "location test device",
"user_id": "5efc67c6a40ad3095d17be18",
"geofence_description": "365",
"geofence_id": "5eecc7491e621663c93ba2fe",
"location_id": "5efc696ca40ad3095d17be79",
"app_id": "5e95cbe83722794cf72ea0af_1",
"event_type": "exit",
"coordinates": {
"type": "Point",
"coordinates": [
80.08113,
12.91806
]
},
"recorded_at": "2020-07-01T10:46:03.000",
"timezone_offset": "+0530",
"created_at": "2020-07-01T10:46:06.459",
"is_deleted": false
},
{
"id": "5efc696a8cb244000185ea29",
"user_description": "location test device",
"user_id": "5efc67c6a40ad3095d17be18",
"geofence_description": "365",
"geofence_id": "5eecc7491e621663c93ba2fe",
"location_id": "5efc6968a40ad3096417bb5f",
"app_id": "5e95cbe83722794cf72ea0af_1",
"event_type": "entry",
"coordinates": {
"type": "Point",
"coordinates": [
80.08572,
12.91959
]
},
"recorded_at": "2020-07-01T10:46:00.000",
"timezone_offset": "+0530",
"created_at": "2020-07-01T10:46:02.379",
"is_deleted": false
}
]
}
}
Explore the Android utility methods related to location permissions.
The Roam SDK is capable of sending push notifications to your users. Add Firebase to your Android project to get the device token.
Roam.setDeviceToken("FCM DeviceToken")
Roam.setDeviceToken("FCM DeviceToken");
This method gets the FCM DeviceToken
from the SDK.
Roam.getDeviceToken()
Roam.getDeviceToken();
Check whether your app has location permission. Returns a boolean, which is true
if location permission has been granted or false
otherwise.
Roam.checkLocationPermission()
Roam.checkLocationPermission();
Check if the device has location services enabled. This method returns a boolean, which is true
if the location services are on and false
otherwise.
Roam.checkLocationServices()
Roam.checkLocationServices();
This utility method checks whether your app has background location permissions. It returns a boolean as true
if background location permission has been granted, or false
otherwise.
Roam.checkBackgroundLocationPermission()
Roam.checkBackgroundLocationPermission();
Call this method to request the user to enable location permissions.
Roam.requestLocationPermission(this)
Roam.requestLocationPermission(this);
override fun onRequestPermissionsResult(requestCode: Int, permissions:
Array<String>, grantResults:IntArray) {
when (requestCode) {
Roam.REQUEST_CODE_LOCATION_PERMISSION->
if (grantResults[0] ==PackageManager.PERMISSION_GRANTED) {
....
} else if (grantResults[0] ==PackageManager.PERMISSION_DENIED) {
....
}
}
}
//Callback from request location permission method.
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case Roam.REQUEST_CODE_LOCATION_PERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
...
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
...
}
break;
}
}
Call this method to enable location services.
Roam.requestLocationServices(this)
Roam.requestLocationServices(this);
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == Roam.REQUEST_CODE_LOCATION_ENABLED) {
....
}
}
//Callback from request location services method.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Roam.REQUEST_CODE_LOCATION_ENABLED) {
}
}
Call this method to request the user to enable background location permissions.
Roam.requestBackgroundLocationPermission(this)
Roam.requestBackgroundLocationPermission(this);
override fun onRequestPermissionsResult(requestCode: Int, permissions:
Array<String>, grantResults: IntArray) {
when (requestCode) {
Roam.REQUEST_CODE_BACKGROUND_LOCATION_PERMISSION->
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
...
}
else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
...
}
}
}
//Callback from request background location permission method.
@Override
public void onRequestPermissionsResult(intrequestCode, Stringpermissions[],
int[] grantResults) {
switch (requestCode) {
case Roam.REQUEST_CODE_BACKGROUND_LOCATION_PERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
...
}
else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
...
}
break;
}
}
Check whether location tracking has been started or not. This method returns a boolean value.
Roam.isLocationTracking()
Roam.isLocationTracking();
Using the updateCurrentLocation
method, you can update the user's current location and set the accuracy ranging from 10 to 100 meters (default is 10).
Roam.updateCurrentLocation(DesiredAccuracy, accuracy)
Roam.updateCurrentLocation(DesiredAccuracy, accuracy);
Parameter
Description
DesiredAccuracy
RoamTrackingMode.DesiredAccuracy.HIGH or RoamTrackingMode.DesiredAccuracy.MEDIUM or RoamTrackingMode.DesiredAccuracy.LOW
Logout from Roam SDK using the logout()
method.
NOTE - You need to reinitialize the SDK to login again.
Roam.logout(object : RoamLogoutCallback {
override fun onSuccess(message: String) {
}
override fun onFailure(roamError: RoamError) {
// Access Error code and message here
// roamError.code
// roamError.message
}
})
Roam.logout(new RoamLogoutCallback() {
@Override
public void onSuccess(String message) {
}
@Override
public void onFailure(RoamError roamError) {
// Access Error code and message here
// roamError.code;
// roamError.message;
}
});
By using this method inside FirebaseMessagingService class, track the campaign impressions and counts.
override fun onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as
NotificationManager
....
intent.putExtra(Roam.EXTRA, Roam.notificationReceiveHandler(remoteMessage.getData()))
....
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
...
intent.putExtra(Roam.EXTRA, Roam.notificationReceiveHandler(remoteMessage.getData()));
...
notificationManager.notify(NotificationID, builder.build());
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
....
Roam.notificationOpenedHandler(intent)
)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
Roam.notificationOpenedHandler(getIntent());
}
When running the SDK on Android 6 (and higher), it is recommended to ask the user to disable battery optimization for your application. This ensures that location tracking continues to work when the device is in Doze mode.
Moreover, on Android Pie, disabling battery optimization prevents Adaptive Battery from bucketing your app based on usage and restricting background processing, which can impact the detection quality of the SDK.
After explaining the benefits of disabling battery optimization, call the disableBatteryOptimization()
method of the Roam class.
Roam.disableBatteryOptimization()
Roam.disableBatteryOptimization();
This will trigger a system dialog asking the user to allow disabling battery optimization for your app.
Roam.isBatteryOptimizationEnabled()
Roam.isBatteryOptimizationEnabled();
Explore the Android SDK Methods for Trip API v1. Check out the latest methods if you are using Trips API v2!
Use the code below to create a trip directly from the SDK. Set Boolean value true
to create offline trips and false
to create online trips.
Roam.createTrip(null, null, Boolean, object : RoamCreateTripCallback {
override fun onSuccess(roamTrip: RoamCreateTrip) {
// do something when create trip success
// access roam trip created timestamp with roamTrip.getCreatedAt
// access roam trip user id with roamTrip.getUserId
// access roam trip id with roamTrip.getTripId
}
override fun onFailure(roamError: RoamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
})
Roam.createTrip(null, null, Boolean, new RoamCreateTripCallback() {
@Override
public void onSuccess(RoamCreateTrip roamTrip) {
// do something when create trip success
// access roam trip created timestamp with roamTrip.getCreatedAt
// access roam trip user id with roamTrip.getUserId
// access roam trip id with roamTrip.getTripId
}
@Override
public void onFailure(RoamError roamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
});
Roam.getTripDetails("ROAM-TRIP-ID", object : RoamTripDetailCallback {
override fun onSuccess(roamTrip: RoamTripDetail) {
// do something when get trip details success
// access roam trip created timestamp with roamTrip.getCreatedAt()
// access roam trip user id with roamTrip.getUserId()
// access roam trip id with roamTrip.getTripId()
}
override fun onFailure(roamError: RoamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
})
Roam.getTripDetails("ROAM-TRIP-ID", new RoamTripDetailCallback() {
@Override
public void onSuccess(RoamTripDetail roamTrip) {
// do something when get trip details success
// access roam trip created timestamp with roamTrip.getCreatedAt()
// access roam trip user id with roamTrip.getUserId()
// access roam trip id with roamTrip.getTripId()
}
@Override
public void onFailure(RoamError roamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
});
Use the code below to start the trip with the previously created tripID.
Roam.startTrip("ROAM-TRIP-ID", "ROAM-TRIP-DESCRIPTION", object : RoamTripCallback {
override fun onSuccess(message: String) {
}
override fun onFailure(roamError: RoamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
})
Roam.startTrip("ROAM-TRIP-ID", "ROAM-TRIP-DESCRIPTION", new RoamTripCallback() {
@Override
public void onSuccess(String message) {
}
@Override
public void onFailure(RoamError roamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
});
Roam.stopTrip("ROAM-TRIP-ID", object : RoamTripCallback {
override fun onSuccess(message: String) {
}
override fun onFailure(roamError: RoamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
})
Roam.stopTrip("ROAM-TRIP-ID", new RoamTripCallback() {
@Override
public void onSuccess(String message) {
}
@Override
public void onFailure(RoamError roamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
});
Use the code below to pause the trip with the previously started trip id.
Roam.pauseTrip("ROAM-TRIP-ID", object : RoamTripCallback {
override fun onSuccess(message: String) {
}
override fun onFailure(roamError: RoamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
})
Roam.pauseTrip("ROAM-TRIP-ID", new RoamTripCallback() {
@Override
public void onSuccess(String message) {
}
@Override
public void onFailure(RoamError roamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
});
To resume the trip,
Roam.resumeTrip("ROAM-TRIP-ID", object : RoamTripCallback {
override fun onSuccess(message: String) {
}
override fun onFailure(roamError: RoamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
})
Roam.resumeTrip("ROAM-TRIP-ID", new RoamTripCallback() {
@Override
public void onSuccess(String message) {
}
@Override
public void onFailure(RoamError roamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
});
Subscribe to tripStatus
using the tripId
to get real-time trip status.
//subscribe to trip status
Roam.subscribeTripStatus("ROAM-TRIP-ID")
//subscribe to trip status
Roam.subscribeTripStatus("ROAM-TRIP-ID");
To stop receiving trip status updates, use the method below.
//unsubscribe to trip status
Roam.unSubscribeTripStatus("ROAM-TRIP-ID")
//unsubscribe to trip status
Roam.unSubscribeTripStatus("ROAM-TRIP-ID");
Roam.getTripStatus("ROAM-TRIP-ID", object : RoamTripStatusCallback {
override fun onSuccess(roamTrip: RoamTripStatus) {
// do something when get trip details success
// access roam trip distance with roamTrip.getDistance()
// access roam trip speed with roamTrip.getSpeed()
}
override fun onFailure(roamError: RoamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
})
Roam.getTripStatus("ROAM-TRIP-ID", new RoamTripStatusCallback() {
@Override
public void onSuccess(RoamTripStatus roamTrip) {
// do something when get trip details success
// access roam trip distance with roamTrip.getDistance()
// access roam trip speed with roamTrip.getSpeed()
}
@Override
public void onFailure(RoamError roamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
});
To retrieve the active trips, set the Boolean value to true
to get offline trips and to false
to get online trips.
Roam.activeTrips(Boolean, object : RoamActiveTripsCallback {
override fun onSuccess(roamTrip: RoamTrip) {
roamTrip.activeTrips
}
override fun onFailure(roamError: RoamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
})
Roam.getTripSummary("ROAM-TRIP-ID", object : RoamTripSummaryCallback {
override fun onSuccess(roamTrip: RoamTripSummary) {
// do something when get trip details success
// access roam trip distance covered with roamTrip.getDistanceCovered
// access roam trip route with roamTrip.getRoute
// access roam trip duration with roamTrip.getDuration
// access roam trip id with roamTrip.getTripId
}
override fun onFailure(roamError: RoamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
})
Roam.getTripSummary("ROAM-TRIP-ID", new RoamTripSummaryCallback() {
@Override
public void onSuccess(RoamTripSummary roamTrip) {
// do something when get trip details success
// access roam trip distance covered with roamTrip.getDistanceCovered
// access roam trip route with roamTrip.getRoute
// access roam trip duration with roamTrip.getDuration
// access roam trip id with roamTrip.getTripId
}
@Override
public void onFailure(RoamError roamError) {
// do something when get trip details error
// access roam error code with roamError.getCode()
// access roam error message with roamError.getMessage()
}
});
Explore how to get multiple trips with our Trip API
GET
https://api.roam.ai/v2/trips
Returns a list of your trips.
starting_after
String
A cursor for use in pagination. starting_after is a trip id that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include starting_after=obj_foo in order to fetch the next page of the list.
ending_before
String
A cursor for use in pagination. ending_before is a trip id that defines your place in the list. For instance, if you make a list request and receive 100 objects, starting with obj_bar, your subsequent call can include ending_before=obj_bar in order to fetch the previous page of the list.
created_at
Condition
A filter on the list based on the object created_at field.
description
Condition
A filter on the list based on the object description field.
trip_state
Condition
A filter on the list based on the object trip_status field.
is_local
Condition
A filter on the list based on the object is_local field.
user_id
Conditon
A filter on the list based on the object user_id field.
limit
Number
A limit on the number of objects to be returned, between 1 and 100.
Authorization*
String
Bearer <API-KEY>
{
"code": 200,
"message": "trip_list_success",
"description": "The lists of trips for requests filter and search options.",
"has_more": false,
"trips": [
{
"id": "620f26ad9ba7360496bc1be7",
"name": "Test Delivery",
"description": "item pickup for test users",
"trip_state": "created",
"total_distance": 0,
"total_duration": 0,
"total_elevation_gain": 0,
"metadata": {
"_id": 21,
"order_id": "1123"
},
"start_location": {},
"end_location": {},
"user": {
"id": "61ffb486d2c69840ee518073",
"name": "",
"description": "1200",
"metadata": {
"Mobile": "1234567890",
"Name": "Nikhil"
}
},
"started_at": null,
"ended_at": null,
"created_at": "2022-02-18T04:55:09.660",
"updated_at": "2022-02-18T04:55:09.660",
"events": [],
"stops": [
{
"id": "620f26ad9ba7360496bc1be5",
"name": "Delivery",
"description": "test Pickup for Johan",
"metadata": {
"order_id": "1120"
},
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
},
"created_at": "2022-02-18T04:55:09.658",
"updated_at": "2022-02-18T04:55:09.658",
"arrived_at": null,
"departed_at": null
},
{
"id": "620f26ad9ba7360496bc1be6",
"name": "Delivery",
"description": "another tester Pickup for Johan",
"metadata": {
"order_id": "1129"
},
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
},
"created_at": "2022-02-18T04:55:09.659",
"updated_at": "2022-02-18T04:55:09.659",
"arrived_at": null,
"departed_at": null
}
]
},
{
...
},
...
]
}
{
"code" : 400,
"message" : "invalid_request_error",
"description": "The request was unacceptable, due to missing a required parameter or invalid parameter.",
"errors" : [
{
"field" : "limit",
"message" : "This field should be a number between 1 and 100"
},
{
"field" : "created_at",
"message" : "This field should be valid ISO date string"
},
{
"field" : "is_local",
"message" : "This field should be valid boolean value"
}
]
}
The following logical operators are generally supported for filters.
Equality operators
Equals eq
Not equals ne
Negation not
In in
Relational operators
Less than lt
Greater than gt
Less than or equal to le
Greater than or equal to ge
Conditional operators
And and
Or or
Functions
Starts with startsWith
Ends with endsWith
Contains contains
Like like
curl --location --request GET 'https://api.roam.ai/v2/trips?limit=100&starting_after=61dec6e206f8a019b2402c0b&ending_before=61dec6e206f8a019b2402c0b&created_at=gt:2022-01-12T12:17:38.625&description=contains:Delivery&trip_state=eq:created&is_local=eq:true&user_id=eq:61dec6e206f8a019b2402c0b&stop_id=eq:61dec6e206f8a019b2402c0b' \
--header 'Authorization: Bearer <API-KEY>'
Explore how to get a single trip with our Trip API
GET
https://api.roam.ai/v2/trips/:id
Returns the trip with the given ID.
id*
String
Retrieves the trip with the given ID.
Authorization*
String
Bearer <API-KEY>
{
"code": 200,
"message": "trip_object",
"description": "The details of trip for requested id.",
"has_more": false,
"trips":
{
"id": "620f26ad9ba7360496bc1be7",
"name": "Test Delivery",
"description": "item pickup for test users",
"trip_state": "created",
"total_distance": 0,
"total_duration": 0,
"total_elevation_gain": 0,
"metadata": {
"_id": 21,
"order_id": "1123"
},
"start_location": {},
"end_location": {},
"user": {
"id": "61ffb486d2c69840ee518073",
"name": "",
"description": "1200",
"metadata": {
"Mobile": "1234567890",
"Name": "Nikhil"
}
},
"started_at": null,
"ended_at": null,
"created_at": "2022-02-18T04:55:09.660",
"updated_at": "2022-02-18T04:55:09.660",
"events": [],
"stops": [
{
"id": "620f26ad9ba7360496bc1be5",
"name": "Delivery",
"description": "test Pickup for Johan",
"metadata": {
"order_id": "1120"
},
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
},
"created_at": "2022-02-18T04:55:09.658",
"updated_at": "2022-02-18T04:55:09.658",
"arrived_at": null,
"departed_at": null
},
{
"id": "620f26ad9ba7360496bc1be6",
"name": "Delivery",
"description": "another tester Pickup for Johan",
"metadata": {
"order_id": "1129"
},
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
},
"created_at": "2022-02-18T04:55:09.659",
"updated_at": "2022-02-18T04:55:09.659",
"arrived_at": null,
"departed_at": null
}
]
}
}
{
"code" : 400,
"message" : "invalid_request_error",
"description": "The request was unacceptable, due to missing a required parameter or invalid parameter.",
"errors" : [
{
"field" : "id",
"message" : "This field should be a valid trip id"
}
]
}
curl --location --request GET 'https://api.roam.ai/v2/trips/620f26ad9ba7360496bc1be7' \
--header 'Authorization: Bearer dfbbf5d5ff6b41ecb1166147b87c0544'
Use this API to update details for an existing geofence of any specific project.
PUT
https://api.roam.ai/v1/api/geofence/
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
geofence_id
string
geofence_id which needs to be updated E.g.- 6dba14deda01857c3c418265
group_ids
array
Enables geofence for the list of users. If group_ids and user_ids are empty then geofence is enabled for all users of the project. E.g.- ["group1","group2"]
user_ids
array
Enables geofence for the list of users. If group_ids and user_ids are empty then geofence is enabled for all users of the project. E.g.-["user1","user2"]
coordinates
array
Mandatory for creating the geofence. E.g.- [ -72.28122, 42.926042 ]
metadata
object
An optional set of custom key-value pairs for the geofence.
geometry_type
string
Defines the type of geometry. E.g.- circle
geometry_radius
integer
Defines the radius of circular geofence in meters. Range 50m to 1000m. (Required only for geometry_type circle. Field value ignored if sent when geometry_type is a polygon.) E.g.- 50m to 1000m max
color_code
string
Defines the color of Geofence and how it is displayed on the dashboard. Type: Hex Code for CSS colors. Note: Pass the code without '#'. E.g.- ffffff
tag
string
Tag the Geofences for future reference and filtering. E.g.- hotel
description
string
Optional description for the geofence. E.g.- This is just a 5 star cool hotel where you can stay.
is_enabled
array
Array with first index depicting whether the geofence is enabled or disabled, second index depicting the start_time and last index depicting the end_time between which the geofence should be active. E.g.- [true,"2021-06-10T20:45:44", "2021-06-15T22:45:33"]
{
"status": true,
"msg": "Geofence updated successfully.",
"code": 200,
"data": {
"geofence_id": "6dba14deda01857c3c418265",
"geometry_radius": 177,
"geometry_center": {
"type": "Point",
"coordinates": [
-72.28122,
42.926042
]
},
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"],
"user_ids": ["6bda16edea01848b3b419163"],
"group_ids": ["5cda16edea00845b3b419173"],
"created_at": "2020-09-29T13:11:08.702",
"updated_at": "2020-09-29T13:11:08.702"
}
}
curl --location --request PUT 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '{
"geofence_id": "6dba14deda01857c3c418265",
"coordinates": [ -72.28122, 42.926042 ] ,
"geometry_radius": 177,
"description": "Roam Amsterdam HQ",
"tag": "Office",
"metadata": {},
"user_ids": ["6bda16edea01848b3b419163"],
"group_ids": ["5cda16edea00845b3b419173"],
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"]
}'
Explore how to start a quick trip on iOS with Trips v2.
The Start Quick Trip method creates and starts a trip immediately.
To create a quick trip, you need to create an object for the trip and assign it with theRoamTrip()
class. Below are the parameters and their descriptions for the trip object.
Along with the above trip object, you need to pass an additional parameter for trackingMode
which is optional and defaults to active tracking mode.
To start a quick trip with custom tracking mode, refer to the following code:
The list of responses, error parameters and their description is given below.
To access the status parameters:
To access trip response:
To access user details:
To access error details:
metadata
dictionary
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
tripName
string
Name of the trip
tripDescription
string
Trip description
isLocal
boolean
Value determining if the trip is a local trip.
response?.code
number
The response code of the method.
response?.message
string
The response message of the method.
tripDetails?.tripId
number
Unique identifier for trip objects.
tripDetails?.metadata
dictionary
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
tripDetails?.tripName
string
Name of the trip.
tripDetails?.tripDescription
string
Trip description
tripDetails?.tripState
string
The current state of the trip is either created, started, or ended.
tripDetails?.isLocal
boolean
Value determining if the trip is a local trip.
tripDetails?.totalDistance
number
The total distance covered by the user for this trip.
tripDetails?.totalDuration
number
The total duration taken by the user for this trip.
tripDetails?.totalElevationGain
number
The total elevation gain covered by the user for this trip.
tripDetails?.createdAt
string
Timestamp of wen the trip was created
tripDetails?.updatedAt
string
Timestamp of when the trip was updated
tripDetails?.startedAt
string
Timestamp of when the trip was started by the user
tripDetails?.endedAt
string
Timestamp of when the trip was ended by the user
user?.userId
string
Unique identifier for the user object.
user?.metadata
dictionary
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
user?.userDescription
string
User description
user?.userName
string
User's full name
error?.code
number
The error response code of the method.
error?.message
string
The error response message of the method.
error?.errorDescription
string
The error response description of the method.
errorDetails?[i].message
string
The message for error detail.
errorDetails?[i].field
string
The field for error detail.
Roam.startTrip(trip, RoamTrackingMode.active) { response, error in
// Access trip response and error here
}
[Roam startTrip:trip :RoamTrackingModeActive :NULL handler:^(RoamTripResponse * response, RoamTripError * error) {
// Access trip response and error here
}];
RoamTrackingCustomMethodsObjcWrapper *customTrackingMode = [[RoamTrackingCustomMethodsObjcWrapper alloc] init];
[customTrackingMode setUpCustomOptionsWithDesiredAccuracy:LocationAccuracyKCLLocationAccuracyBest
useVisit:false showsBackgroundLocationIndicator:true
distanceFilter:10 useSignificant:false
useRegionMonitoring:false useDynamicGeofencRadius:false
geofenceRadius:0 allowBackgroundLocationUpdates:true
activityType:CLActivityTypeFitness pausesLocationUpdatesAutomatically:true
useStandardLocationServices:false accuracyFilter:10 updateInterval:10];
[Roam startTracking:RoamTrackingModeCustom options:customTrackingMode];
// Define a custom tracking method
let customTrackingMode = RoamTrackingCustomMethods()
// Update the settings for the created method as per need
customTrackingMode.activityType = .fitness
customTrackingMode.pausesLocationUpdatesAutomatically = true
customTrackingMode.showsBackgroundLocationIndicator = true
customTrackingMode.useSignificant = false
customTrackingMode.useRegionMonitoring = false
customTrackingMode.useVisits = false
customTrackingMode.accuracyFilter = 10
customTrackingMode.desiredAccuracy = .kCLLocationAccuracyNearestTenMeters
// Update the distance intervel as per the use case in meters
customTrackingMode.distanceFilter = 10
Roam.startTrip(trip, RoamTrackingMode.custom, customTrackingMode ) { response, error in
// Access trip response and error here
}
user_id
string
Used to get the list of trips assigned to the given user_id. E.g.- 5d9450ace47bae6d70064a9b
start_date
string
Date from when trips need to be returned. E.g.- 2020-08-15
end_date
string
Date till when the trip list needs to be returned. E.g.- 2020-08-20
trip_id
string
Used to get one particular trip. E.g.- 5f7d9926e5fc233610297c76
page_number
integer
Used to traverse through pages of data. E.g.- 1
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
curl --location --request GET 'https://api.roam.ai/v1/api/trips/?user_id=5f7d95f1ffb3fb58435309de' \
--header 'Api-key: 4db3d709296a4a518a03bf15f37c55b7' \
--header 'Content-Type: application/json'
{
"status": true,
"msg": "Success.",
"code": 200,
"data": [
{
"id": "5f7d9926e5fc233610297c76",
"project_id": "5f7d656ae5fc233611297c6c",
"origins": [
{
"id": "5f7d9926e5fc233610297c77",
"trip_id": "5f7d9926e5fc233610297c76",
"created_at": "2021-06-07T10:32:06.527",
"updated_at": "2021-06-07T10:32:06.538",
"coordinates": {
"type": "Point",
"coordinates": [
77.622977,
12.917042
]
},
"loc_type": "origin"
},
{
"id": "5f7d9926e5fc233610297c78",
"trip_id": "5f7d9926e5fc233610297c76",
"created_at": "2021-06-07T10:32:06.545",
"updated_at": "2021-06-07T10:32:06.552",
"coordinates": {
"type": "Point",
"coordinates": [
77.650239,
12.924304
]
},
"loc_type": "origin"
},
{
"id": "5f7d9926e5fc233610297c79",
"trip_id": "5f7d9926e5fc233610297c76",
"created_at": "2021-06-07T10:32:06.560",
"updated_at": "2021-06-07T10:32:06.571",
"coordinates": {
"type": "Point",
"coordinates": [
77.743206,
12.954302
]
},
"loc_type": "origin"
}
],
"destinations": [
{
"id": "5f7d9926e5fc233610297c7a",
"trip_id": "5f7d9926e5fc233610297c76",
"created_at": "2021-06-07T10:32:06.578",
"updated_at": "2021-06-07T10:32:06.584",
"coordinates": {
"type": "Point",
"coordinates": [
78.743206,
12.954302
]
},
"loc_type": "destination"
}
],
"events": [
{
"id": "5f7d99298fd7a058fbff9ff9",
"trip_id": "5f7d9926e5fc233610297c76",
"user_id": "5f7d95f1ffb3fb58435309de",
"event_type": "geospark:trip:created",
"created_at": "2021-06-07T10:32:09.699",
"is_deleted": false,
"event_source": "geospark:trip",
"event_version": "1.0"
}
],
"user_id": "5f7d95f1ffb3fb58435309de",
"is_started": false,
"is_ended": false,
"is_deleted": false,
"created_at": "2021-06-07T10:32:06.522",
"updated_at": "2021-06-07T10:32:06.603"
}
]
}
The Get Location API provides a list of locations of the users who are using your app for a specified project corresponding to the project secret API key provided by you.
GET
https://api.roam.ai/v1/api/location/
user_id
string
user_id for which the locations have to be returned. E.g.- 5d9450ace47bae6d70064a9b
start_date
string
Date from when the location is to be fetched. E.g.- 2021-05-31T18:48:52
end_date
string
Date till when the location is to be returned. E.g.- 2021-05-31T18:48:58
timezone_offset
string
If the timezone is provided the response will be returned as the provided local timezone.
If the timezone is not provided, the response will be returned in UTC.
If points_encoded value istrue
, then this value will be UTC by default.
E.g.- Asia/Kolkata
page_number
integer
This field is used for getting 10 entries at a time.
If the response returns an empty list in the data field, the pages are exhausted.
If points_encoded value istrue
, then this value will not be considered.
E.g.- 1
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
{
"status": true,
"msg": "Success.",
"code": 200,
"data": {
"next_page": 2,
"pages": 208,
"prev_page": null,
"app_id": "61dfb41b06f8a05d35522133_2",
"user_id": "61fa120106f8a03320a88e71",
"locations": [{
"altitude": 892.3450775146484,
"tz_offset": "+0530",
"vertical_accuracy": 19.1458740234375,
"network_status": true,
"tracking_mode": "manual",
"battery_remaining": 15,
"activity": "STOP",
"app_context": "F",
"battery_status": "charging",
"speed": 0,
"location_permission": true,
"horizontal_accuracy": 17.071232461095033,
"course": -1,
"coordinates": {
"type": "Point",
"coordinates": [77.61589418628188, 12.900758328664052]
},
"created_at": "2022-08-10T13:51:16.066",
"recorded_at": "2022-08-10T13:51:12.877",
"id": "62f3b7d00000c4b052de369a"
}, {
"battery_status": "unplugged",
"network_status": true,
"battery_saver": false,
"tracking_mode": "passive",
"battery_remaining": 5,
"activity": "MOVING",
"course": -1,
"speed": 0,
"vertical_accuracy": 23.39385414123535,
"tz_offset": "+0530",
"horizontal_accuracy": 17.071232461095033,
"app_context": "B",
"location_permission": true,
"altitude": 892.3696823120117,
"coordinates": {
"type": "Point",
"coordinates": [77.61589418628188, 12.900758328664052]
},
"created_at": "2022-08-10T13:12:00.915",
"recorded_at": "2022-08-10T13:11:55.164",
"id": "62f3ae9b0000afe64ac6cac5"
}, {
"horizontal_accuracy": 1414,
"network_status": true,
"battery_saver": false,
"altitude": 0,
"battery_status": "unplugged",
"location_permission": true,
"speed": 0,
"course": -1,
"battery_remaining": 5,
"vertical_accuracy": -1,
"tracking_mode": "passive",
"app_context": "B",
"tz_offset": "+0530",
"activity": "STOP",
"coordinates": {
"type": "Point",
"coordinates": [77.61679076999997, 12.900112149999995]
},
"created_at": "2022-08-10T13:12:00.915",
"recorded_at": "2022-08-10T13:11:55.150",
"id": "62f3ae9b0000f98b18c6cac4"
}, {
"altitude": 893.5367736816406,
"battery_status": "unplugged",
"horizontal_accuracy": 17.071232461095033,
"network_status": true,
"location_permission": true,
"tracking_mode": "passive",
"vertical_accuracy": 20.849611282348633,
"battery_remaining": 45,
"speed": 0,
"app_context": "B",
"activity": "MOVING",
"tz_offset": "+0530",
"course": -1,
"coordinates": {
"type": "Point",
"coordinates": [77.61589418628188, 12.900758328664052]
},
"created_at": "2022-08-10T00:42:49.415",
"recorded_at": "2022-08-10T00:42:48.478",
"id": "62f2ff800000c14b1ba8f09f"
}, {
"vertical_accuracy": 8.873176330313447,
"network_status": true,
"horizontal_accuracy": 16.806443087050994,
"tracking_mode": "manual",
"altitude": 893.2683876520023,
"speed": 0,
"location_permission": true,
"battery_status": "unplugged",
"course": -1,
"activity": "STOP",
"battery_remaining": 51,
"app_context": "B",
"tz_offset": "+0530",
"coordinates": {
"type": "Point",
"coordinates": [77.61586109896076, 12.900552716084862]
},
"created_at": "2022-08-09T22:22:45.874",
"recorded_at": "2022-08-09T22:22:45.424",
"id": "62f2de350000137fdfa8f09e"
}, {
"battery_status": "unplugged",
"location_permission": true,
"app_context": "F",
"network_status": true,
"course": -1,
"tz_offset": "+0530",
"horizontal_accuracy": 17.071232461095033,
"vertical_accuracy": 20.690359115600586,
"activity": "MOVING",
"speed": 0,
"battery_remaining": 51,
"altitude": 893.362922668457,
"tracking_mode": "passive",
"coordinates": {
"type": "Point",
"coordinates": [77.61589418628188, 12.900758328664052]
},
"created_at": "2022-08-09T22:12:50.800",
"recorded_at": "2022-08-09T22:12:47.305",
"id": "62f2dbdf00004d8e9fa8f09d"
}, {
"battery_remaining": 51,
"altitude": 893.2115707397461,
"tz_offset": "+0530",
"battery_status": "unplugged",
"horizontal_accuracy": 17.071232461095033,
"activity": "MOVING",
"course": -1,
"network_status": true,
"battery_saver": false,
"tracking_mode": "passive",
"speed": 0,
"app_context": "F",
"location_permission": true,
"vertical_accuracy": 20.604103088378906,
"coordinates": {
"type": "Point",
"coordinates": [77.61589418628188, 12.900758328664052]
},
"created_at": "2022-08-09T22:12:45.797",
"recorded_at": "2022-08-09T22:12:43.647",
"id": "62f2dbdb0000c2501ca8f09c"
}, {
"battery_status": "unplugged",
"location_permission": true,
"app_context": "F",
"network_status": true,
"course": -1,
"tz_offset": "+0530",
"horizontal_accuracy": 17.071232461095033,
"vertical_accuracy": 20.604103088378906,
"activity": "MOVING",
"speed": 0,
"battery_remaining": 51,
"battery_saver": false,
"altitude": 893.2115707397461,
"tracking_mode": "passive",
"coordinates": {
"type": "Point",
"coordinates": [77.61589418628188, 12.900758328664052]
},
"created_at": "2022-08-09T22:12:45.796",
"recorded_at": "2022-08-09T22:12:41.600",
"id": "62f2dbd9000030ef66a8f09b"
}, {
"battery_saver": false,
"battery_status": "unplugged",
"horizontal_accuracy": 40,
"activity": "STOP",
"speed": 0,
"app_context": "F",
"tracking_mode": "passive",
"course": -1,
"location_permission": true,
"network_status": true,
"battery_remaining": 51,
"vertical_accuracy": -1,
"tz_offset": "+0530",
"altitude": 0,
"coordinates": {
"type": "Point",
"coordinates": [77.6159101969165, 12.900724173934503]
},
"created_at": "2022-08-09T22:12:45.796",
"recorded_at": "2022-08-09T22:12:41.586",
"id": "62f2dbd90000c6975aa8f09a"
}, {
"network_status": true,
"horizontal_accuracy": 17.071232461095033,
"battery_remaining": 51,
"vertical_accuracy": 8.44229507446289,
"battery_status": "unplugged",
"activity": "STOP",
"course": -1,
"tz_offset": "+0530",
"altitude": 892.7507934570312,
"app_context": "B",
"location_permission": true,
"speed": 0,
"tracking_mode": "manual",
"coordinates": {
"type": "Point",
"coordinates": [77.61589418628188, 12.900758328664052]
},
"created_at": "2022-08-09T22:11:25.785",
"recorded_at": "2022-08-09T22:11:21.548",
"id": "62f2db89000079b041a8f099"
}]
}
}
curl --location --request GET 'https://api.roam.ai/v1/api/location/?start_date=2022-08-09T00:00:00&end_date=2022-08-15T10:00:00&user_id=61fa120106f8a03320a88e71' \
--header 'Api-key: e190697f74b64ac8ad0273a13c06e94f'
Explore how to create a trip on Android with Trips v2.
To create a trip, you need to create an object for the trip and assign it with the RoamTrip() builder class. Below are the parameters and their descriptions for the trip object.
metadata
JSONObject
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
tripName
String
The name of the trip
tripDescription
String
The description for the trip
isLocal
boolean
Value determining if the trip is a local trip.
user
String
The user ID
Stops
List <RoamTripStops>
The list of stop object
When you create a trip, you can add stop locations which are nothing but locations where the user taking the trip will receive events for entry and exit. To create and assign stops to a trip, create objects for a single or multiple stops and assign them with the RoamTripStops() class. Below are the parameters and their descriptions for the stop object.
metadata
JSONObject
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
stopName
String
The stop name
stopDescription
String
The stop description
geometryRadius
Double
The stop radius
geometry
List<Double>
The coordinates list with longitude and latitude.
address
String
The stop address
Below is an example code for creating a trip with two stops. Let's create our stop objects.
JSONObject metadata = new JSONObject();
metadata.put("Key", "value");
List<Double> geometry1 = new ArrayList<>();
geometry1.add(23.5155215);
geometry1.add(85.30614739);
List<Double> geometry2 = new ArrayList<>();
geometry2.add(12.9716);
geometry2.add(77.5946);
RoamTripStops stop1 = new RoamTripStops();
stop1.setMetadata(metadata);
stop1.setStopDescription("description");
stop1.setStopName("name");
stop1.setAddress("address");
stop1.setGeometryRadius(100.0);
stop1.setGeometry(geometry1);
RoamTripStops stop2 =new RoamTripStops();
stop2.setStopId("");
stop2.setMetadata(metadata);
stop2.setStopDescription("description");
stop2.setStopName("name");
stop2.setAddress("address");
stop2.setGeometryRadius(600.0);
stop2.setGeometry(geometry2);
List<RoamTripStops> stop = new ArrayList<>();
stop.add(stop1);
stop.add(stop2);
val metadata = JSONObject()
metadata.put("Key", "value")
val geometry1: MutableList<Double> = ArrayList()
geometry1.add(23.5155215)
geometry1.add(85.30614739)
val geometry2: MutableList<Double> = ArrayList()
geometry2.add(12.9716)
geometry2.add(77.5946)
val stop1 = RoamTripStops()
stop1.setMetadata(metadata)
stop1.setStopDescription("description")
stop1.setStopName("name")
stop1.setAddress("address")
stop1.setGeometryRadius(100.0)
stop1.setGeometry(geometry1)
val stop2 = RoamTripStops()
stop2.setStopId("")
stop2.setMetadata(metadata)
stop2.setStopDescription("description")
stop2.setStopName("name")
stop2.setAddress("address")
stop2.setGeometryRadius(600.0)
stop2.setGeometry(geometry2)
val stop: MutableList<RoamTripStops> = ArrayList()
stop.add(stop1)
stop.add(stop2)
Now, let's create an object for the trip and update the parameters along with stop which was created above.
RoamTrip trip = new RoamTrip.Builder()
.setUserId("userId")
.setMetadata(metadata)
.setTripDescription("description")
.setTripName("name")
.setIsLocal(true)
.setStop(stop)
.build();
val trip: RoamTrip? = RoamTrip.Builder()
.setUserId("userId")
.setMetadata(metadata)
.setTripDescription("description")
.setTripName("name")
.setIsLocal(true)
.setStop(stop)
.build()
Now that the trip and stop objects are created, let's create the trip with Roam.createTrip() method.
Roam.createTrip(trip, new RoamTripCallback() {
@Override
public void onSuccess(RoamTripResponse response) {
//get trip details
}
@Override
public void onError(Error error) {
//get error details
}
});
Roam.createTrip(trip, object : RoamTripCallback {
override fun onSuccess(response: RoamTripResponse) {
//get trip details
}
override fun onError(error: Error?) {
//get error details
}
})t
The list of responses and error parameters are given below with their descriptions.
To access the status parameters:
response.getCode()
Integer
The response code of the method.
response.getMessage()
String
The response message of the method.
To access the trip response:
getTripDetails().getTripId()
String
Unique identifier for the object.
getTripDetails().getMetadata()
Object
Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
getTripDetails().getTripName()
String
The name of the trip
getTripDetails().getTripDescription()
String
The trip’s description
getTripDetails().getTripState()
String
The current state of the trip is either created, started, or ended.
getTripDetails().getIsLocal()
boolean
Value determining if the trip is a local trip.
getTripDetails().getTotalDistance()
double
The total distance covered by the user for this trip.
getTripDetails().getTotalDuration()
double
The total duration taken by the user for this trip.
getTripDetails().getTotalElevationGain()
double
The total elevation gain covered by the user for this trip.
getTripDetails().createdAt()
String
Timestamp of when the trip was created
getTripDetails().updatedAt()
String
Timestamp of when the trip was updated
getTripDetails().startedAt()
String
Timestamp of when the trip was started by the user
getTripDetails().endedAt()
String
Timestamp of when the trip was ended by the user
To access user details:
getUser().getId()
String
Unique identifier for the object.
getUser().getMetadata()
Object
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
getUser().getDescription()
String
User description
getUser().getName()
String
The user's full name
To access stop details:
getStops().get(i).getStopName()
String
The stop name
getStops().get(i).getStopDescription()
String
The stop description
getStops().get(i).getMetadata()
Object
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
getStops().get(i).getGeometryRadius()
double
The stop radius.
getStops().get(i).getGeometry()
Object
The coordinates list with longitude and latitude.
getStops().get(i).getArrivedAt()
String
The timestamp when the user arrived at the stop.
getStops().get(i).getDepartedAt()
String
The timestamp when the user departed from the stop.
getStops().get(i).getAddress()
String
The stop address .
To access error details:
error.getErrorCode()
Integer
The error response code of the method.
error.getErrorMessage()
String
The error response message of the method.
error.getErrorDescription()
String
The error response description of the method.
error.getErrors().get(i).getMessage()
String
The message for error detail.
error.getErrors.get(i).getField()
String
The field for error detail.
Keep yourself updated on any Android changes.
We're excited to introduce Roam Android SDK version 0.1.23, focusing on refining our location filters to improve accuracy during location tracking. In this update, we've made the following improvement:
Enhanced Location Filtering: We've refined our location filters to effectively discard drifts and noises during location tracking. This enhancement aims to improve the accuracy and reliability of location data, ensuring a more precise representation of user movement.
These improvements are geared towards providing a more accurate and dependable location tracking experience for developers and users. We're dedicated to enhancing your tracking capabilities and ensuring a smoother operational experience. Should you have any inquiries or feedback, our support team is readily available to assist you.
We're excited to introduce Roam Android SDK version 0.1.22, focusing on refining our location filters to improve accuracy during location tracking. In this update, we've made the following improvement:
Enhanced Location Filtering: We've refined our location filters to effectively discard drifts and noises during location tracking. This enhancement aims to improve the accuracy and reliability of location data, ensuring a more precise representation of user movement.
These improvements are geared towards providing a more accurate and dependable location tracking experience for developers and users. We're dedicated to enhancing your tracking capabilities and ensuring a smoother operational experience. Should you have any inquiries or feedback, our support team is readily available to assist you.
We're thrilled to present Roam Android SDK version 0.1.21, focusing on bolstering our security module. In this update, we've made significant improvements to enhance the security module of location tracking. Here's what's new:
Efficient Spoofed Location Detection: Our security algorithm has been refined to efficiently discard spoofed locations during the initial location fix. This enhancement ensures that only genuine and accurate location data is captured, enhancing the authenticity of the information gathered.
Addressing False Negatives: We've tackled false negatives during location tracking, ensuring that true locations are not mistakenly identified as spoofed locations. This refinement enhances the precision of location tracking, providing you with reliable and accurate data.
These security enhancements are designed to safeguard your data and ensure the integrity of the location information collected by the Roam Android SDK. Your security is our priority, and we're committed to providing you with a secure and trustworthy experience. If you have any questions, concerns, or feedback, our support team is always here to assist you.
We are thrilled to introduce Roam Android SDK version 0.1.20, a significant step forward in enhancing your tracking experience. Here's what's new:
New Callbacks for Enhanced Control: With added success and error callbacks to methods like startTracking
, stopTracking
, subscribe
, unSubscribe
, publishAndSave
, and stopPublishing
, you now have precise control and real-time feedback for every SDK action.
Extended Security Checks: We've expanded the toggleSecurity()
method with two vital parameters. Now, you can check for connected external accessories and Bluetooth status, bolstering security measures for your application.
Your feedback has played a pivotal role in shaping these enhancements. Should you have any questions, encounter issues, or want to share your experiences, our dedicated support team is here to assist you.
We're excited to announce the latest release of the Roam Android SDK, version 0.1.19. This update brings a significant enhancement that contributes to heightened security and user control. Read on to discover the key highlights of this release:
New Feature: Motion Detection Security
With Roam Android SDK v0.1.19, we introduce an innovative security feature—Motion Detection. This cutting-edge capability adds an extra layer of protection to your application's tracking experience. By enabling the verifyMotion parameter in the toggleSecurity()
method, developers can now leverage motion patterns to enhance security. This empowers you to monitor and respond to unusual motion activities, ensuring a safer and more reliable tracking environment.
Your feedback and insights have been instrumental in shaping the Roam Android SDK, and we're grateful for your ongoing support. If you have any questions, suggestions, or need assistance, please don't hesitate to contact our support team. As we strive to continually refine and enhance the SDK, look forward to more updates on the horizon.
We're pleased to unveil Roam Android SDK version 0.1.18, showcasing an exciting new feature that enhances security and user control. Here's an overview of the latest updates:
New Security Module: Roam
In this release, we introduce the Roam Security Module, a powerful addition to the SDK's arsenal. With the Roam module, developers now have access to the toggleSecurity()
method, a versatile tool that allows the seamless activation and deactivation of advanced security mechanisms. Prioritizing data security is vital, and the Roam Security Module empowers developers to safeguard sensitive information more effectively.
Your feedback and insights have been instrumental in shaping the Roam Android SDK, and we're grateful for your ongoing support. If you have any questions, suggestions, or need assistance, please don't hesitate to contact our support team. As we strive to continually refine and enhance the SDK, look forward to more updates on the horizon.
Added a new feature to get publish key from local.properties gradle file.
Fixed order of callbacks for create and get user methods and MQTT connection.
Added stationary duration for all tracking modes except time base.
Fixed noise and duplicate locations update.
Improved location accuracy.
Added post notification support for android 13.
Removed work manager concept from SDK.
Fixed work manager dependency version for react native SDK support.
Fixed dynamic distance filter logic.
Fixed location update gap in time base tracking.
Added noise filter in time base tracking.
Fixed batch location update issue.
Fixed trip sync issue.
Fixed multiple location update and speed inconsistent issue.
Fixed multiple callback issue for trip methods.
Added activity recognition to reduce battery consumption for default tracking modes.
Added basic ingest publish topic for aws cost optimisation.
Fixed deprecated code and time out error for get current location method.
Fixed deprecated code and time out error for get current location method.
Fixed get current location method.
Removed isTripSynced method (no longer required).
Fixed updateCurrentLocation method, RoamPublish param can be null.
Fixed getActiveTrip method, if isLocal is true then get offline trips in response and vice-versa.
Fixed getActiveTrip method, trip stops point should be in response.
Fixed updateTrip method, isLocal param should not be required to update a trip.
Added SDK installation support for android 13.
Added hourly location count feature.
Fixed the Roam SDK installation support for android 13.
Added magnetic bearing support.
Added meta data support for setDescription method.
Added tracking config feature.
Added app service class parameter to setForegroundNotification method.
Added magnetic bearing feature in SDK.
Added metadata support for the setDescription()
method.
Added custom configuration support for Roam.initialize() method .
Fixed the noise location update for distance-based tracking and stationary location update.
Fixed the execution order of MQTT connection callback and createUser/getUser method's callback.
Fixed location update gap in stationary location update.
Fixed location update when the device gets restarted.
Fixed tracking config logic for time base tracking.
Added:
There should be a locations count field.
Batch update support for the trip listener.
Batch update support for location listener.
Network listener method for connectivity change.
Modified:
Create trip method should support creating trips without a user id.
Subscribe trip method should support the online trip.
Update trip method should be based on trip state.
Sync trip should have speed parameter.
Roam trip status should have trip state as parameter.
Unsubscribe trip method support for multiple trips.
Update time stamp field in trip listener.
Trip status code for control trip .
Fixed:
Offline trip reached_stop and left stop event are not getting called.
Drift issue fix.
Added course field for offline trip
Fixed:
Fixed location update gap in distance-based tracking.
Fixed stationary noise locations update when device gets stationary.
Fixed:
Fixed Timestamp of offline trip events.
Added:
Tracking configuration method for location accuracy improvement.
Added:
Unsubscribe trip method for multiple trips ID.
Added timestamp field in the trip status listener.
Fixed quick trip response.
Fixed:
Location drift issue.
Receiver intent leaking issue
Added:
Batch location update feature for trips.
Fixed:
Location listener and connectivity change listener issue.
Added:
Network listener method for connectivity change.
Added:
Batch location update feature.
Location count field for trips.
Modified:
Trip errors response.
Fixed:
Fixed time-based tracking issue.
Modified:
RoamPublish parameter as optional in updateCurrentLocation method.
Fixed:
Removed noise locations update when the device gets idle during tracking.
Updated new trip V2 methods. Refer to the Migration guide.
Fixed:
Connection configuration for security and performance.
Fixed:
Fixed stationary location update issue.
Fixed:
Fixed logical error in the calculation of elevation gain in trips summary.
Fixed:
Added option in Roam.unSubscribe()
which will now unsubscribe all users if user_id
is passed as null or empty.
Added battery and network details as part of location in location receiver. Fixed invalid location update data.
Fixed:
Foreground notification method support for android 12.
Fixed:
SDK installation support for Android 12.
Modified:
Removed location permission status frequent updates.
Added:
Added "initialize validation" for each method.
Modified:
Removed user-id validation for offline trips in the createTrip
method.
Added:
Added foreground service notification in SDK.
Added elevation gain support for offline trips.
Removed user-id validation for offline trips.
Added:
Implemented location permission status.
Added:
Support location subscription for cross-project within the same Account.
Fixed:
Issue fixed on the location receiver method.
Modified:
Make startTrip
independent by combining it with startTracking
and createTrip
methods
Added:
metadata
support for users and trips were added
Modified:
Resolves #11 Allow meta-data support for updating location ie. updateCurrentLocation
method
Removed:
Resolves #9 Combine startTracking
and startSelfTracking methods
Resolved #9 Combined startTracking and startSelfTracking methods
Added:
Added the total elevation gain parameter to the already existing elevation gain, distance, and duration parameters in the trip summary.
Fixed:
Fixed location receiver callbacks.
The first version of Roam Android SDK
Explore how to control a trip with our Trip API
POST
https://api.roam.ai/v2/trips/:id/controls
Starts/Pauses/Resumes/Stops the trip for the given id.
id*
String
Updates the trip with the given ID.
Authorization*
String
Bearer <API-KEY>
user_id*
String
The user for which the trip is being tracked.
started_at*
String
Timestamp is UTC for action:start eg: 2022-01-14T09:10:59.125
action*
String
To control the trip.
eg. start, pause, resume, end
paused_at*
String
Timestamp is UTC for action:pause eg: 2022-01-14T09:10:59.125
resumed_at*
String
Timestamp is UTC for action:resume eg: 2022-01-14T09:10:59.125
ended_at*
String
Timestamp is UTC for action:end eg: 2022-01-14T09:10:59.125
{
"code": 201,
"message": "trip_updated",
"description": "The trip data is updated successfully for given id.",
"trip": {
"id": "620f26ad9ba7360496bc1be7",
"name": "Test Delivery",
"description": "item pickup for test users",
"trip_state": "created",
"total_distance": 0,
"total_duration": 0,
"total_elevation_gain": 0,
"metadata": {
"_id": 21,
"order_id": "1123"
},
"start_location": {},
"end_location": {},
"user": {
"id": "61ffb486d2c69840ee518073",
"name": "",
"description": "1200",
"metadata": {
"Mobile": "1234567890",
"Name": "Nikhil"
}
},
"started_at": null,
"ended_at": null,
"created_at": "2022-02-18T04:55:09.660",
"updated_at": "2022-02-18T04:55:09.660",
"events": [],
"stops": [
{
"id": "620f26ad9ba7360496bc1be5",
"name": "Delivery",
"description": "test Pickup for Johan",
"metadata": {
"order_id": "1120"
},
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
},
"created_at": "2022-02-18T04:55:09.658",
"updated_at": "2022-02-18T04:55:09.658",
"arrived_at": null,
"departed_at": null
},
{
"id": "620f26ad9ba7360496bc1be6",
"name": "Delivery",
"description": "another tester Pickup for Johan",
"metadata": {
"order_id": "1129"
},
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
},
"created_at": "2022-02-18T04:55:09.659",
"updated_at": "2022-02-18T04:55:09.659",
"arrived_at": null,
"departed_at": null
}
]
}
}
{
"code" : 400,
"message" : "invalid_request_error",
"description": "The request was unacceptable, due to missing a required parameter or invalid parameter.",
"errors" : [
{
"field" : "user_id",
"message" : "This field should be a valid user id"
},
{
"field" : "stops.id",
"message" : "This field should be a valid stop id"
},
{
"field" : "stops.geometry_radius",
"message" : "This field should be valid number between 10 and 10000"
}
]
}
curl --location --request POST 'https://api.roam.ai/v2/trips' \
--header 'Authorization: Bearer dfbbf5d5ff6b41ecb1166147b87c0544' \
--header 'Content-Type: application/json' \
--data-raw '{
"user_id": "61ffb486d2c69840ee518073",
"description": "item pickup for test users",
"name": "Test Delivery",
"metadata": {
"order_id": "1123",
"_id": 21
},
"stops": [
{
"metadata": {"order_id": "1120"},
"description": "test Pickup for Johan",
"name": "Delivery",
"address": "Flat NO 121 MG road ",
"geometry_radius": 20,
"geometry": {
"type": "Point",
"coordinates": [
77.6879689,
27.4072289
]
}
},
{
"metadata": {"order_id": "1129"},
"description": "another tester Pickup for Johan",
"name": "Delivery",
"address": "teacher colony ",
"geometry_radius": 200,
"geometry": {
"type": "Point",
"coordinates": [
77.6925657818137,
27.422398561298454
]
}
}
]
}'
Explore how to publish and subscribe locations for Android.
Once our SDK is initialized, we need to create or get a user to start the tracking and use other methods. Each user created will have a unique Roam identifier which will be used later to login and access developer APIs. You can call it Roam userId.
Adding metadata to users is optional and you can pass null while creating users to ignore that field.
// create user with meta-data and description
// Declare meta-data as json
// Description as string
val metadata = JSONObject()
metadata.put("key", "value")
Roam.createUser("SET-USER-DESCRIPTION-HERE", metadata, object : RoamCallback {
override fun onSuccess(roamUser: RoamUser) {
// Access Roam user data below
// roamUser.getUserId();
// roamUser.getDescription();
// roamUser.getEventListenerStatus();
// roamUser.getLocationListenerStatus();
// roamUser.getLocationEvents();
// roamUser.getGeofenceEvents();
// roamUser.getMovingGeofenceEvents();
// roamUser.getTripsEvents();
}
override fun onFailure(roamError: RoamError) {
// Access the error code & message below
// roamError.getCode()
// roamError.getMessage()
}
})
// update user with meta-data and description
// Declare meta-data as dictionary
// Description as string
JSONObject metadata = new JSONObject();
metadata.put("key", "value");
Roam.createUser("YOUR-USER-DESCRIPTION-GOES-HERE", metadata, new RoamCallback() {
@Override
public void onSuccess(RoamUser roamUser) {
// Access Roam user data below
// roamUser.getUserId();
// roamUser.getDescription();
// roamUser.getEventListenerStatus();
// roamUser.getLocationListenerStatus();
// roamUser.getLocationEvents();
// roamUser.getGeofenceEvents();
// roamUser.getMovingGeofenceEvents();
// roamUser.getTripsEvents();
}
@Override
public void onFailure(RoamError roamError) {
// Access error code & message below
// roamError.getCode();
// roamError.getMessage();
}
});
The "user description" option can be used to update your user information such as name, address or add an existing user ID. Make sure the information is encrypted if you are planning to save personal user information like email or phone number.
You can always set or update user descriptions and meta-data later using the code below.
// update user with meta-data and description
// Declare meta-data as dictionary
// Description as string
val metadata = JSONObject()
metadata.put("key", "value")
Roam.setDescription("SET-USER-DESCRIPTION-HERE", metadata)
// update user with meta-data and description
// Declare meta-data as dictionary
// Description as string
JSONObject metadata = new JSONObject();
metadata.put("key", "value");
Roam.setDescription("SET-USER-DESCRIPTION-HERE", metadata);
If you already have a Roam userID that you would like to reuse instead of creating a new user, use the below to get the user session.
Roam.getUser("ROAM-USER-ID", object : RoamCallback {
override fun onSuccess(roamUser: RoamUser) {
// Access Roam user data below
// roamUser.getUserId();
// roamUser.getDescription();
// roamUser.getEventListenerStatus();
// roamUser.getLocationListenerStatus();
// roamUser.getLocationEvents();
// roamUser.getGeofenceEvents();
// roamUser.getMovingGeofenceEvents();
// roamUser.getTripsEvents();
}
override fun onFailure(roamError: RoamError) {
// Access error code & message below
// roamError.getCode()
// roamError.getMessage()
}
})
Roam.getUser("YOUR-ROAM-USER-ID", new RoamCallback() {
@Override
public void onSuccess(RoamUser roamUser) {
// Access Roam user data below
// roamUser.getUserId();
// roamUser.getDescription();
// roamUser.getEventListenerStatus();
// roamUser.getLocationListenerStatus();
// roamUser.getLocationEvents();
// roamUser.getGeofenceEvents();
// roamUser.getMovingGeofenceEvents();
// roamUser.getTripsEvents();
}
@Override
public void onFailure(RoamError roamError) {
// Access error code & message below
// roamError.getCode();
// roamError.getMessage();
}
});
To publish and subscribe to location data, startSelfTracking
methods have to be changed to startTracking
Roam.startTracking(TrackingMode, object:TrackingCallback(){
override fun onSuccess(s: String?) {
//do something
}
override fun onError(roamError: RoamError?) {
//do something
}
})
Roam.startTracking(TrackingMode, new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
Specify the tracking mode while you use the startTracking
method Roam.startTracking
Roam has three default tracking modes along with a custom version. They differ based on the frequency of location updates and battery consumption. The higher the frequency, the higher the battery consumption. You must use foreground service for continuous tracking.
Mode
Battery usage
Updates every
Optimised for/advised for
Active
6% - 12%
25 ~ 250 meters
Ride Hailing / Sharing
Balanced
3% - 6%
50 ~ 500 meters
On Demand Services
Passive
0% - 1%
100 ~ 1000 meters
Social Apps
// active tracking
Roam.startTracking(RoamTrackingMode.ACTIVE, object:TrackingCallback(){
override fun onSuccess(s: String?) {
//do something
}
override fun onError(roamError: RoamError?) {
//do something
}
})
// balanced tracking
Roam.startTracking(RoamTrackingMode.BALANCED, object:TrackingCallback(){
override fun onSuccess(s: String?) {
//do something
}
override fun onError(roamError: RoamError?) {
//do something
}
})
// passive tracking
Roam.startTracking(RoamTrackingMode.PASSIVE, object:TrackingCallback(){
override fun onSuccess(s: String?) {
//do something
}
override fun onError(roamError: RoamError?) {
//do something
}
})
// active tracking
Roam.startTracking(RoamTrackingMode.ACTIVE, new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
// balanced tracking
Roam.startTracking(RoamTrackingMode.BALANCED, new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
// passive tracking
Roam.startTracking(RoamTrackingMode.PASSIVE, new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
Our SDK also provides a custom tracking mode that allows you to customize and build your own tracking modes.
Type
Unit
Unit Range
Distance Interval
Meters
1m ~ 2500m
Time Interval
Seconds
10s ~ 10800s
Distance between location updates example code:
// Define a custom tracking method with desired distance interval, stop duration and accuracy
val trackingMode = RoamTrackingMode.Builder(<DISTANCE-FILTER-IN-METERS>, <STOP-INTERVAL-IN-SECONDS>)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build()
// Start the tracking with the above created custom tracking method
Roam.startTracking(trackingMode, object:TrackingCallback(){
override fun onSuccess(s: String?) {
//do something
}
override fun onError(roamError: RoamError?) {
//do something
}
})
// Define a custom tracking method with desired distance interval, stop duration and accuracy
RoamTrackingMode trackingMode = new RoamTrackingMode.Builder(<DISTANCE-FILTER-IN-METERS>, <STOP-INTERVAL-IN-SECONDS>)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build();
// Start the tracking with the above created custom tracking method
Roam.startTracking(trackingMode, new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
Time between location updates example code:
// Define a custom tracking method with desired time interval and accuracy
val trackingMode = RoamTrackingMode.Builder(<TIME-INTERVAL-IN-SECONDS>)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build()
// Start the tracking with the above created custom tracking method
Roam.startTracking(trackingMode, object:TrackingCallback(){
override fun onSuccess(s: String?) {
//do something
}
override fun onError(roamError: RoamError?) {
//do something
}
})
// Define a custom tracking method with desired time interval and accuracy
RoamTrackingMode trackingMode = new RoamTrackingMode.Builder(<TIME-INTERVAL-IN-SECONDS>)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build();
// Start the tracking with the above created custom tracking method
Roam.startTracking(trackingMode, new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
You may see a delay if the user's device is in low power mode or has connectivity issues.
To stop the tracking use the below method.
Roam.stopTracking(object : TrackingCallback {
override fun onSuccess(s: String) {
//do something
}
override fun onError(roamError: RoamError) {
//do something
}
})
Roam.stopTracking(new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
Publishing will help publish location data that will be stored in our database and sent to Roam servers for further processing.
Location data will be published and sent to the Roam servers for further processing. The data will be saved on our database servers.
val locationData = RoamPublish.Builder().build()
Roam.publishAndSave(locationData, object : PublishCallback {
override fun onSuccess(s: String) {
//do something
}
override fun onError(roamError: RoamError) {
//do something
}
})
RoamPublish locationData = new RoamPublish.Builder().build();
Roam.publishAndSave(locationData, new PublishCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
You can now send custom meta-data json values along with location data in publishAndSave
method.
val data = JSONObject()
data.put("Key", "Value")
val roamPublish = RoamPublish.Builder()
.metadata(data)
.build()
Roam.publishAndSave(roamPublish, object : PublishCallback {
override fun onSuccess(s: String) {
//do something
}
override fun onError(roamError: RoamError) {
//do something
}
})
JSONObject data = new JSONObject();
data.put("Key", "Value");
RoamPublish roamPublish = new RoamPublish.Builder()
.metadata(data)
.build();
Roam.publishAndSave(roamPublish, new PublishCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
To stop publishing locations,
Roam.stopPublishing(object : PublishCallback {
override fun onSuccess(s: String) {
//do something
}
override fun onError(roamError: RoamError) {
//do something
}
})
Roam.stopPublishing(new PublishCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
Now that you have enabled the location listener, use the below method to subscribe to your own or other user's location updates and events.
Roam.subscribe(TYPE, "ROAM-USER-ID", object : SubscribeCallback {
override fun onSuccess(s: String, s1: String) {
//do something
}
override fun onError(roamError: RoamError) {
//do something
}
})
Roam.subscribe(TYPE, "USER-ID", new SubscribeCallback() {
@Override
public void onSuccess(String s, String s1) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
Roam.unSubscribe(TYPE, "ROAM-USER-ID", object : SubscribeCallback {
override fun onSuccess(s: String, s1: String) {
//do something
}
override fun onError(roamError: RoamError) {
//do something
}
})
Roam.unSubscribe(TYPE, "ROAM-USER-ID", new SubscribeCallback() {
@Override
public void onSuccess(String s, String s1) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
Type
Description
Roam.Subscribe.EVENTS
Subscribe to your own events.
Roam.Subscribe.LOCATION
Subscribe to your own location (or) other user's location updates.
Roam.Subscribe.BOTH
Subscribe to your own events and location (or) other user's location updates.
You can pass an empty user_id which is an optional field from v0.0.14 to unsubscribe from all the users.
Before adding listeners for locations and other data, we need to toggle the listener flags for the user in order to get the data.
To do that, you need to set the location and event listener to true
using the below method. By default, the status will be set to false
and needs to be set to true
in order to stream the location and event updates to the same device or other devices.
Roam.toggleListener(locations, events, object : RoamCallback {
override fun onSuccess(roamUser: RoamUser) {
// do something when toggle listener success
// access location listener status with roamUser.getLocationListenerStatus()
// access event listener status with roamUser.getEventListenerStatus()
}
override fun onFailure(roamError: RoamError) {
// do something when toggle listener failure
}
})
Roam.toggleListener(true, true, new RoamCallback() {
@Override
public void onSuccess(RoamUser roamUser) {
// Access Roam user data below
// roamUser.getUserId();
// roamUser.getDescription();
// roamUser.getEventListenerStatus();
// roamUser.getLocationListenerStatus();
// roamUser.getLocationEvents();
// roamUser.getGeofenceEvents();
// roamUser.getMovingGeofenceEvents();
// roamUser.getTripsEvents();
}
@Override
public void onFailure(RoamError roamError) {
// Access error code & message below
// roamError.getCode();
// roamError.getMessage();
}
});
You can also get the current status of listeners with the below method.
Roam.getListenerStatus(object : RoamCallback {
override fun onSuccess(roamUser: RoamUser) {
// do something when get listener status success
// get location listener status with roamUser.getLocationListenerStatus
// get event listener status with roamUser.getEventListenerStatus
}
override fun onFailure(roamError: RoamError) {
// do something when get listener status failure
}
})
Roam.getListenerStatus(new RoamCallback() {
@Override
public void onSuccess(RoamUser roamUser) {
// Access Roam user data below
// roamUser.getUserId();
// roamUser.getDescription();
// roamUser.getEventListenerStatus();
// roamUser.getLocationListenerStatus();
// roamUser.getLocationEvents();
// roamUser.getGeofenceEvents();
// roamUser.getMovingGeofenceEvents();
// roamUser.getTripsEvents();
}
@Override
public void onFailure(RoamError roamError) {
// Access error code & message below
// roamError.getCode();
// roamError.getMessage();
}
});
To listen to events on the server-side, you should enable events for the user using the method below.
Roam.toggleEvents(geofence, trip, location, movingGeofence, object : RoamCallback {
override fun onSuccess(roamUser: RoamUser) {
// do something when toggle events success
// access location event status with roamUser.getLocationEvents()
// access geofence event status with roamUser.getGeofenceEvents()
// access trip events status with roamUser.getTripsEvents()
// get moving geofence event status with roamUser.getMovingGeofenceEvents()
}
override fun onFailure(error: roamError) {
// do something when toggle events failure
}
Roam.toggleEvents(true, true, true, true, new RoamCallback() {
@Override
public void onSuccess(RoamUser roamUser) {
// Access Roam user data below
// roamUser.getUserId();
// roamUser.getDescription();
// roamUser.getEventListenerStatus();
// roamUser.getLocationListenerStatus();
// roamUser.getLocationEvents();
// roamUser.getGeofenceEvents();
// roamUser.getMovingGeofenceEvents();
// roamUser.getTripsEvents();
}
@Override
public void onFailure(RoamError roamError) {
// Access error code & message below
// roamError.getCode();
// roamError.getMessage();
}
});
Now, to listen to location updates and events, create a class that extends RoamReceiver. Then register the receiver by adding a receiver element to the application element in your manifest.
<application>
...
<receiver android:name=".LocationReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.roam.android.RECEIVED"/>
</intent-filter>
</receiver>
...
</application>
Then add the code to the receiver.
public class LocationReceiver : RoamReceiver() {
override fun onLocationUpdated(context: Context, roamLocations: MutableList<RoamLocation>) {
// receive own location updates here
// do something with location data using location
}
override fun onLocationReceived(context: Context, roamLocationReceived: RoamLocationReceived) {
// receive other user's location updates here
// do something with location
}
override fun onEventReceived(context: Context, roamEvent: RoamEvent) {
//access event data here
}
override fun onReceiveTripStatus(context: Context, listener:List<TripStatusListener>) {
// receive real time trip status here
// do something with trip status data
}
override fun onError(context: Context, roamError: RoamError) {
//access error data here
}
}
public class LocationReceiver extends RoamReceiver {
@Override
public void onLocationUpdated(Context context, List<RoamLocation> roamLocations) {
// receive own location updates here
// do something with location data using location
}
@Override
public void onLocationReceived(Context context, RoamLocationReceived roamLocationReceived) {
// receive other user's location updates here
// do something with location
}
@Override
public void onEventReceived(Context context, RoamEvent roamEvent) {
//access event data here
}
@Override
public void onReceiveTripStatus(Context context,List<TripStatusListener> listener) {
// receive real time trip status here
// do something with trip status data
}
@Override
public void onError(Context context, RoamError roamError) {
//access error data here
}
}
The Roam Android SDK makes it quick and easy to build a location tracker for your Android app. We provide powerful and customizable tracking modes and features.
To use the Roam SDK,
Get yourself a free Roam Account. No credit card is required.
Create a project and add an Android app to the project.
You need the PUBLISHABLE_KEY
(available in your project settings) to initialize the SDK.
Now, you’re ready to integrate the SDK into your Android application.
Roam Android SDK requires Android Studio 2.0 or later and is compatible with apps targeting Android SDK Version 16 or above.
The Roam Example repository on GitHub includes sample applications that demonstrate the use of the v3 Roam SDK for Android.
To run an example app, clone this repository, navigate to the example app in paths Example/
, add your publishable YOUR-PUBLISHABLE-KEY
key in MainApplication.java
, and run the app.
Make sure the package name
is the same as the one registered on our Roam dashboard.
To use the Android SDK in a project, add the SDK as a build dependency and sync the project.
Go to Android Studio > New Project > Minimum SDK
Select API 16: Android 4.1.0 (Jelly Bean) or higher and create a project
After you create a new project, open Gradle Scripts > build.gradle (Project: <your_project>) and do the following:
Add the following to the build script {repositories {}} section of the build.gradle (Project)file:
mavenCentral()
Sync and close build.gradle (Project: <your_project>)
To install the SDK for your project via Gradle
in Android Studio, add the maven below to your project build.gradle
file.
repositories {
maven {
url 'https://com-roam-android.s3.amazonaws.com/'
}
}
add the dependencies below to your app build.gradle
file.
dependencies {
implementation 'com.roam.sdk:roam-android:0.1.20'
}
Then sync Gradle.
Download and unzip the Roam SDK.
Open Android Studio and add the SDK Roam.aar
as a module using File > New > New Module > Import .JAR/.AAR Package.
Once Gradle is finished, click File > Project Structure again.
Click on the Dependencies tab > click App > click the “+” icon in the top left of the Declared Dependencies section > select Module Dependency > click on Roam-release > press Ok and wait for Gradle to sync again.
Make sure to include the dependencies separately and sync your project.
dependencies {
implementation 'com.google.android.gms:play-services-location:17.0.0'
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.4'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
}
Roam SDK offers a flexible method of initialization, allowing developers to seamlessly integrate our services into their applications. With our latest update, we've introduced a new initialization approach using Manifest file. This method provides an effortless way to set up your Roam SDK without the need for additional code.
Using Manifest file Initialization:
Optional Parameter: Publish Key
The publishKey
parameter in the initialization method is now optional.
If you've added your Roam publish key to your project's Manifest
file, there's no need to pass the publishKey
parameter during initialization.
Configure Your Manifest File:
In your Manifest
file, declare your Roam publish key as follows:
<meta-data
android:name="com.roam.lib.sdk.PUBLISH_KEY"
android:value="${ROAM_PUBLISH_KEY}" />
Replace ${ROAM_PUBLISH_KEY}
with your actual Roam publish key.
Using local.properties (Optional):
Alternatively, you can use a local.properties
file to feed the Roam publish key to the Manifest
file.
In your local.properties
file, add the following line, replacing XXXXXXXXXXXXXX
with your Roam publish key:
ROAM_PUBLISH_KEY = XXXXXXXXXXXXXX
To get Roam publish key from local.properties to Manifest, user must have to add following code in build.gradle(app)
defaultConfig {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
manifestPlaceholders = [ROAM_PUBLISH_KEY: "${properties.getProperty('ROAM_PUBLISH_KEY')}"]
}
Initialization Code:
Initialize Roam SDK in your application class as follows:
If the publish key is added to the Manifest file, the initialize
method can be called without passing the publishable key.
Roam.initialize(this)
Roam.initialize(this);
By following these steps, you can seamlessly initialize Roam SDK using manifest file, simplifying the integration process and saving valuable development time.
Using Application class Initialization:
Before initializing the SDK, the below must be imported.
import com.roam.sdk.Roam;
After importing, add the code below under the Application class onCreate()
method. The SDK must be initialized before calling any of the other SDK methods.
Roam.initialize(this, "YOUR-SDK-KEY-GOES-HERE")
Roam.initialize(this, "YOUR-SDK-KEY-GOES-HERE");
To request the location for devices running both below/above Android 10, refer to the following piece of code.
if (!Roam.checkLocationServices()) {
Roam.requestLocationServices(this)
} else if (!Roam.checkLocationPermission()) {
Roam.requestLocationPermission(this)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !Roam.checkBackgroundLocationPermission()) {
Roam.requestBackgroundLocationPermission(this)
}
if (!Roam.checkLocationServices()) {
Roam.requestLocationServices(this);
} else if (!Roam.checkLocationPermission()) {
Roam.requestLocationPermission(this);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !Roam.checkBackgroundLocationPermission()) {
Roam.requestBackgroundLocationPermission(this);
}
Roam.startTracking(TrackingMode, object:TrackingCallback(){
override fun onSuccess(p0: String?) {
//do something
}
override fun onError(p0: RoamError?) {
//do something
}
})
Roam.startTracking(TrackingMode, new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
Specify the tracking modes while you use the Roam.startTracking
method.
Roam has three default tracking modes along with a custom version. They differ based on the frequency of location updates and battery consumption. The higher the frequency, the higher the battery consumption. You must use the foreground service for continuous tracking.
Mode
Battery usage
Updates every
Optimized for/advised for
Active
6% - 12%
25 ~ 250 meters
Ride Hailing / Sharing
Balanced
3% - 6%
50 ~ 500 meters
On Demand Services
Passive
0% - 1%
100 ~ 1000 meters
Social Apps
// active tracking
Roam.startTracking(RoamTrackingMode.ACTIVE, object:TrackingCallback(){
override fun onSuccess(p0: String?) {
//do something
}
override fun onError(p0: RoamError?) {
//do something
}
})
// balanced tracking
Roam.startTracking(RoamTrackingMode.BALANCED, object:TrackingCallback(){
override fun onSuccess(p0: String?) {
//do something
}
override fun onError(p0: RoamError?) {
//do something
}
})
// passive tracking
Roam.startTracking(RoamTrackingMode.PASSIVE, object:TrackingCallback(){
override fun onSuccess(p0: String?) {
//do something
}
override fun onError(p0: RoamError?) {
//do something
}
})
// active tracking
Roam.startTracking(RoamTrackingMode.ACTIVE, object:TrackingCallback(){
override fun onSuccess(p0: String?) {
//do something
}
override fun onError(p0: RoamError?) {
//do something
}
})
// balanced tracking
Roam.startTracking(RoamTrackingMode.BALANCED, object:TrackingCallback(){
override fun onSuccess(p0: String?) {
//do something
}
override fun onError(p0: RoamError?) {
//do something
}
})
// passive tracking
Roam.startTracking(RoamTrackingMode.PASSIVE, object:TrackingCallback(){
override fun onSuccess(p0: String?) {
//do something
}
override fun onError(p0: RoamError?) {
//do something
}
})
The SDK also provides a custom tracking mode that allows you to customize and build your own tracking modes.
With distance interval tracking you create a tracking mode with a distance interval in meters of your choice.
Type
Unit
Unit Range
Distance Interval
Meters
1m ~ 2500m
Distance between location updates example code:
// Define a custom tracking method with desired distance interval, stop duration and accuracy
val trackingMode = RoamTrackingMode.Builder(<DISTANCE-FILTER-IN-METERS>, <STOP-INTERVAL-IN-SECONDS>)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build()
// Start the tracking with the above created custom tracking method
Roam.startTracking(trackingMode, object:TrackingCallback(){
override fun onSuccess(p0: String?) {
//do something
}
override fun onError(p0: RoamError?) {
//do something
}
})
// Define a custom tracking method with desired distance interval, stop duration and accuracy
RoamTrackingMode trackingMode = new RoamTrackingMode.Builder(<DISTANCE-FILTER-IN-METERS>, <STOP-INTERVAL-IN-SECONDS>)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build();
// Start the tracking with the above created custom tracking method
Roam.startTracking(trackingMode, new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
With Time Interval Tracking you can create a tracking mode with the time interval (in seconds) of your choice.
Type
Unit
Unit Range
Time Interval
Seconds
10s ~ 10800s
Time between location updates example code:
// Define a custom tracking method with desired time interval and accuracy
val trackingMode = RoamTrackingMode.Builder(<TIME-INTERVAL-IN-SECONDS>)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build()
// Start the tracking with the above created custom tracking method
Roam.startTracking(trackingMode, object:TrackingCallback(){
override fun onSuccess(p0: String?) {
//do something
}
override fun onError(p0: RoamError?) {
//do something
}
})
// Define a custom tracking method with desired time interval and accuracy
RoamTrackingMode trackingMode = new RoamTrackingMode.Builder(<TIME-INTERVAL-IN-SECONDS>)
.setDesiredAccuracy(RoamTrackingMode.DesiredAccuracy.HIGH)
.build();
// Start the tracking with the above created custom tracking method
Roam.startTracking(trackingMode, new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
You may see a delay if the user's device is in low power mode or has connectivity issues.
To stop tracking, use the method below.
Roam.stopTracking(object : TrackingCallback {
override fun onSuccess(s: String) {
//do something
}
override fun onError(roamError: RoamError) {
//do something
}
})
Roam.stopTracking(new TrackingCallback() {
@Override
public void onSuccess(String s) {
//do something
}
@Override
public void onError(RoamError roamError) {
//do something
}
});
Listeners are needed to consume the location or event data from the SDK. To enable listeners, ensure the following:
To listen to location updates, create a class that extends RoamReceiver.
Register the receiver by adding a receiver element to the application element in your manifest.
<application>
...
<receiver android:name=".LocationReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.roam.android.RECEIVED"/>
</intent-filter>
</receiver>
...
</application>
Add the code to the receiver.
class LocationReceiver: RoamReceiver() {
override fun onLocationUpdated(context: Context?, roamLocations: MutableList<RoamLocation>?) {
super.onLocationUpdated(context, roamLocations)
// receive own location updates here
// do something with location data using location
for (roamLocation in roamLocations!!){
roamLocation.activity
roamLocation.recordedAt
roamLocation.timezoneOffset
roamLocation.metadata
roamLocation.batteryStatus
roamLocation.networkStatus
roamLocation.location.latitude
roamLocation.location.longitude
roamLocation.location.bearing
roamLocation.location.altitude
roamLocation.location.accuracy
roamLocation.location.speed
roamLocation.location.provider
roamLocation.location.time
roamLocation.location.verticalAccuracyMeters
}
}
override fun onError(context: Context?, roamError: RoamError?) {
super.onError(context, roamError)
// receive error message here
roamError?.code
roamError?.message
}
}
public class LocationReceiver extends RoamReceiver {
@Override
public void onLocationUpdated(Context context, List<RoamLocation> roamLocations) {
super.onLocationUpdated(context, roamLocations);
// receive own location updates here
// do something with location data using location
for(RoamLocation roamLocation: roamLocations){
roamLocation.getActivity();
roamLocation.getRecordedAt();
roamLocation.getTimezoneOffset();
roamLocation.getMetadata();
roamLocation.getBatteryStatus();
roamLocation.getNetworkStatus();
roamLocation.getLocation().getLatitude();
roamLocation.getLocation().getLongitude();
roamLocation.getLocation().getBearing();
roamLocation.getLocation().getAltitude();
roamLocation.getLocation().getAccuracy();
roamLocation.getLocation().getSpeed();
roamLocation.getLocation().getProvider();
roamLocation.getLocation().getTime();
roamLocation.getLocation().getVerticalAccuracyMeters();
}
}
@Override
public void onError(Context context, RoamError roamError) {
super.onError(context, roamError);
// receive error message here
roamError.getCode();
roamError.getMessage();
}
}
Batch configuration lets you control the number of location data updates being received in the location listener with the desired frequency and window.
As the name suggests, this method sets the configuration parameters.
The NetworkState.BOTH
indicates the state in which the updates are to be received. It can either be set to online, offline, or both.
The batchCount
indicates the size of the location batch.
The batchWindow
indicates the time interval for every consecutive update (frequency of updates).
Roam.setBatchReceiverConfig(
NetworkState.BOTH,
batchCount,
batchWindow,
object : RoamBatchReceiverCallback {
override fun onSuccess(list: List<BatchReceiverConfig>) {
list[i].networkState
list[i].batchCount
list[i].batchWindow
}
override fun onFailure(roamError: RoamError) {
roamError.code
roamError.message
}
})
Roam.setBatchReceiverConfig(NetworkState.BOTH, batchCount,
batchWindow, new RoamBatchReceiverCallback() {
@Override
public void onSuccess(List<BatchReceiverConfig> batchReceiverConfig) {
batchReceiverConfig.get(i).getNetworkState();
batchReceiverConfig.get(i).getBatchCount();
batchReceiverConfig.get(i).getBatchWindow();
}
@Override
public void onFailure(RoamError error) {
error.getMessage();
error.getCode();
} });
Consider the following call,
Roam.setBatchConfig("NetworkState.Both
", 5 , 60)
The batch count value is the number of location updates sent in a batch. In the above case, the value is set to 5. Ideally, the SDK sends 5 updates per batch and the batch window (in the above case, 60) specifies the number of seconds the SDK waits to receive five location updates.
If the SDK receives 5 location updates in less than 60 seconds, the updates are pushed to the listener. If not, it waits for 60 seconds and pushes the location updates regardless of the batch count value.
Success Callback - We receive a list of BatchReceiveConfig objects.
Example response:
[{"batchCount":5,"batchWindow":10,"networkState":"OFFLINE"}, {"batchCount":5,"batchWindow":10,"networkState":"ONLINE"}]
Error Callback: We receive a RoamError object in the error callback.
The available details to get from the RoamError object are: error.getMessage() and error.getCode()
The get receiver config method allows the user to get the current batch configuration for the location listener.
Roam.getBatchReceiverConfig(object : RoamBatchReceiverCallback {
override fun onSuccess(list: List<BatchReceiverConfig>) {
list[i].networkState
list[i].batchCount
list[i].batchWindow
}
override fun onFailure(roamError: RoamError) {
roamError.code
roamError.message
}
})
Roam.getBatchReceiverConfig(new RoamBatchReceiverCallback() {
@Override
public void onSuccess(List<BatchReceiverConfig> batchReceiverConfig) {
batchReceiverConfig.get(i).getNetworkState();
batchReceiverConfig.get(i).getBatchCount();
batchReceiverConfig.get(i).getBatchWindow();
}
@Override
public void onFailure(RoamError error) {
error.getMessage();
error.getCode();
} });
The response for the above code is the same as that of the Set Receiver Config method.
The Reset Batch Configuration method allows the user to reset the batch config for the location listener.
Roam.resetBatchReceiverConfig(object : RoamBatchReceiverCallback {
override fun onSuccess(list: List<BatchReceiverConfig>) {
list[i].networkState
list[i].batchCount
list[i].batchWindow
}
override fun onFailure(roamError: RoamError) {
roamError.code
roamError.message
}
})
Roam.resetBatchReceiverConfig(new RoamBatchReceiverCallback() {
@Override
public void onSuccess(List<BatchReceiverConfig> batchReceiverConfig) {
batchReceiverConfig.get(i).getNetworkState();
batchReceiverConfig.get(i).getBatchCount();
batchReceiverConfig.get(i).getBatchWindow();
}
@Override
public void onFailure(RoamError error) {
error.getMessage();
error.getCode();
} });Roam.resetBatchReceiverConfig(object : RoamBatchReceiverCallback {
override fun onSuccess(list: List<BatchReceiverConfig>) {
list[i].networkState
list[i].batchCount
list[i].batchWindow
}
override fun onFailure(roamError: RoamError) {
roamError.code
roamError.message
}
})
Explore how to create a trip on iOS with Trips v2.
To create a trip, you need to create a trip object and assign it with the RoamTrip() class. Below are the parameters and their descriptions for the trip object.
When you create a trip, you can add stop locations which are nothing but locations where the user taking the trip will receive events for entry and exit. To create and assign stops to a trip, create objects for a single or multiple stops and assign them with the RoamTripStops() class. Below are the parameters and their descriptions for the stop object.
Below is an example code for creating a trip with two stops. Let's create our stop objects.
Now, let's create a trip object and update the parameters along with the stop created above.
Now, with the trip and stop objects created, let's create the trip with Roam.createTrip() method.
The list of responses, error parameters and their description is given below.
To access status parameters:
To access trip response:
To access user details:
To access stop details:
To access the error details:
This API helps you to get the trip summary for a given trip_id with its route, distance and duration. Note: distance_covered is in meters and the duration is in seconds.
metadata
dictionary
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
tripName
string
The trip name
tripDescription
string
The trip’s description
isLocal
boolean
The value determining if the trip is a local trip.
user
string
The user object
stops
array
The list of stop object
metadata
dictionary
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
stopName
string
The stop name
stopDescription
string
The stop description
geometryRadius
number
The stop radius
geometryCoordinates
array
Coordinates with longitude, latitude.
address
string
The stop address
let trip = RoamTrip()
trip.user = "userId"
trip.metadata = ["key":"value"]
trip.tripName = "name"
trip.tripDescription = "description"
trip.isLocal = true
trip.stops = [stop]
RoamTrip *trip = [[RoamTrip alloc] init];
[trip setMetadata:@{@"key": @"value"}];
[trip setTripName:@"name"];
[trip setTripDescription:@"description"];
[trip setIsLocal:true];
[trip setStops:@[stop]];
Roam.createTrip(trip) {response,error in
// Access status
// response?.code
// response?.message
// To access trip details
let tripDetails = response?.trip
// Access trip details parameter with tripDetails object
// To access trip user details
let user = tripDetails?.user
// Access trip user details parameter with user object
// To access stop details
let stops = tripDetails?.stops
// Access trip stop details parameter with stops array
}
[Roam createTrip:trip handler:^(RoamTripResponse * response, RoamTripError * error) {
// Access status
// response?.code
// response?.message
// To access trip details
RoamTrip *tripDetails = response.trip;
// Access trip details parameter with tripDetails object
// To access trip user details
RoamUser * user = tripDetails.user
// Access trip user details parameter with user object
// To access stop details
RoamTripStop *stops = tripDetails.stops;
// Access trip stop details parameter with stops array
}];
response?.code
number
The response code of the method.
response?.message
string
The response message of the method.
Parameter
Type
Description
tripDetails?.tripId
number
Unique identifier for the trip object.
tripDetails?.metadata
dictionary
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
tripDetails?.tripName
string
The trip name
tripDetails?.tripDescription
string
The trip description
tripDetails?.tripState
string
The current state of the trip, created, started, or ended.
tripDetails?.isLocal
boolean
Value determining if the trip is a local trip.
tripDetails?.totalDistance
number
The total distance covered by the user for this trip.
tripDetails?.totalDuration
number
The total duration taken by the user for this trip.
tripDetails?.totalElevationGain
number
The total elevation gain covered by the user for this trip.
tripDetails?.createdAt
string
Timestamp of when the trip was created
tripDetails?.updatedAt
string
Timestamp of when the trip was updated
tripDetails?.startedAt
string
Timestamp when the trip was started by the user
tripDetails?.endedAt
string
Timestamp when the trip was ended by the user
Parameter
Type
Description
user?.userId
string
Unique identifier for the user object.
user?.metadata
dictionary
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
user?.userDescription
string
User description
user?.userName
string
User's full name
Parameter
Type
Description
stops?[i].stopName
string
The stop name
stops?[i].stopDescription
string
The stop description
stops?[i].metadata
dictionary
A set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
stops?[i].geometryRadius
string
The stop radius
stops?[i].geometryCoordinates
array
Coordinates with longitude , latitude.
stops?[i].arrivedAt
string
Timestamp of when the user arrived at the stop
stops?[i].departedAt
string
Timestamp of when the user departed from the stop
stops?[i].address
string
The stop address
Parameter
Type
Description
error?.code
number
The error response code of the method.
error?.message
string
The error response message of the method.
error?.errorDescription
string
The error response description of the method.
errorDetails?[i].message
string
The message for error details.
errorDetails?[i].field
string
The field for error details.
RoamTripStop *stop = [[RoamTripStop alloc] init];
[stop setAddress:@"address"];
[stop setMetadata:@{@"key": @"value"}];
[stop setStopDescription:@"description"];
[stop setGeometryRadius:@100];
// logitude , latitude
[stop setGeometryCoordinates:@[@10.1,@10.1]];
let stop = RoamTripStop()
stop.address = "address"
stop.metadata = ["key":"value"]
stop.stopName = "name"
stop.stopDescription = "description"
stop.geometryRadius = 100
// logitude , latitude
stop.geometryCoordinates = [10.1,10.1]
trip_id
string
Trip_id of the trip. E.g.- 5cd0299d77aebe2d78758d32
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
curl --location --request GET 'https://api.roam.ai/v1/api/trips/summary/?trip_id=60bdiuy006f8a03affc5968a' \
--header 'Api-key: 63598c5b3aa84f14914013700402bbc6'
{
"status": true,
"msg": "Success.",
"code": 200,
"data": {
"trip_id": "60bdebd006f8a03affc5968a",
"user_id": "60bdebb051efb059ab7daf67",
"project_id": "60af306a8ce7db2392eb7a75",
"trip_status": "completed",
"distance_covered": 129.25,
"duration": 791,
"route_indexes": [
[
1,
6
],
[
7,
8
],
[
9,
10
],
[
11,
12
],
[
13,
14
],
[
15,
16
],
[
17,
18
],
[
19,
20
],
[
21,
22
],
[
23
]
],
"route": [
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06944606259113,
25.605387669529264
]
},
"altitude": 55.26,
"activity": "STOP",
"recorded_at": "2021-06-07T09:50:53.344",
"duration": 0,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06933924413998,
25.60538919064786
]
},
"altitude": 55.41,
"activity": "MOVING",
"recorded_at": "2021-06-07T09:51:17.232",
"distance": 10.71,
"duration": 23,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06922514582031,
25.60543086974654
]
},
"altitude": 55.17,
"activity": "MOVING",
"recorded_at": "2021-06-07T09:51:46.472",
"distance": 23.05,
"duration": 53,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06934236442666,
25.605409750585785
]
},
"altitude": 55.1,
"activity": "MOVING",
"recorded_at": "2021-06-07T09:51:59.177",
"distance": 35.04,
"duration": 65,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06926644486715,
25.605338334863347
]
},
"altitude": 55.2,
"activity": "MOVING",
"recorded_at": "2021-06-07T09:53:26.418",
"distance": 46.04,
"duration": 153,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06948839273373,
25.60535318995217
]
},
"altitude": 55.39,
"activity": "STOP",
"recorded_at": "2021-06-07T09:56:55.008",
"distance": 68.36,
"duration": 361,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.0696403400277,
25.605349751588847
]
},
"altitude": 55.7,
"activity": "STOP",
"recorded_at": "2021-06-07T09:57:06.271",
"distance": 68.36,
"duration": 361,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06963043776017,
25.60536547480913
]
},
"altitude": 55.63,
"activity": "STOP",
"recorded_at": "2021-06-07T09:57:17.229",
"distance": 70.37,
"duration": 372,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.0696539020383,
25.605395658660587
]
},
"altitude": 55.81,
"activity": "STOP",
"recorded_at": "2021-06-07T09:57:30.023",
"distance": 70.37,
"duration": 372,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06974352418014,
25.60534320757614
]
},
"altitude": 55.57,
"activity": "STOP",
"recorded_at": "2021-06-07T09:57:53.778",
"distance": 81.08,
"duration": 396,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06974881589383,
25.605281419845706
]
},
"altitude": 55.64,
"activity": "STOP",
"recorded_at": "2021-06-07T09:58:09.240",
"distance": 81.08,
"duration": 396,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.0696629610238,
25.60548954876263
]
},
"altitude": 55.94,
"activity": "STOP",
"recorded_at": "2021-06-07T09:58:25.454",
"distance": 105.77,
"duration": 412,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06961812544034,
25.6054897625167
]
},
"altitude": 55.37,
"activity": "STOP",
"recorded_at": "2021-06-07T09:58:33.947",
"distance": 105.77,
"duration": 412,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06957021187245,
25.605456725096815
]
},
"altitude": 55.19,
"activity": "STOP",
"recorded_at": "2021-06-07T09:58:49.033",
"distance": 111.82,
"duration": 427,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06954017101675,
25.60544866085004
]
},
"altitude": 55.22,
"activity": "STOP",
"recorded_at": "2021-06-07T09:58:57.831",
"distance": 111.82,
"duration": 427,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.0694966539289,
25.605459740246193
]
},
"altitude": 55.18,
"activity": "STOP",
"recorded_at": "2021-06-07T09:59:11.070",
"distance": 116.35,
"duration": 440,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.0694966539289,
25.605459740246193
]
},
"altitude": 55.18,
"activity": "STOP",
"recorded_at": "2021-06-07T09:59:22.460",
"distance": 116.35,
"duration": 440,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.0694966539289,
25.605459740246193
]
},
"altitude": 55.18,
"activity": "STOP",
"recorded_at": "2021-06-07T09:59:35.226",
"distance": 116.35,
"duration": 453,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06940685335138,
25.605458887846826
]
},
"altitude": 55.03,
"activity": "STOP",
"recorded_at": "2021-06-07T09:59:47.560",
"distance": 116.35,
"duration": 453,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06931932513449,
25.605412577919306
]
},
"altitude": 55.22,
"activity": "STOP",
"recorded_at": "2021-06-07T10:00:29.244",
"distance": 126.53,
"duration": 495,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06932052635601,
25.605400950443308
]
},
"altitude": 55.43,
"activity": "STOP",
"recorded_at": "2021-06-07T10:01:43.687",
"distance": 126.53,
"duration": 495,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06932052635601,
25.605400950443308
]
},
"altitude": 55.43,
"activity": "STOP",
"recorded_at": "2021-06-07T10:01:56.587",
"distance": 126.53,
"duration": 508,
"elevation_gain": 0
},
{
"coordinates": {
"type": "Point",
"coordinates": [
85.06934078651096,
25.605384688483593
]
},
"altitude": 55.48,
"activity": "STOP",
"recorded_at": "2021-06-07T10:06:40.153",
"distance": 129.25,
"duration": 791,
"elevation_gain": 0
}
],
"total_elevation_gain": 0
}
}
The Get User API provides a list of users who are using your app corresponding to the project secret API key provided.
GET
https://api.roam.ai/v1/api/user/
user_id
string
Used to get the details of one particular user. Note: This query param cannot be used along with any other.
timezone_offset
string
If the timezone is provided the query will be made as per the given timezone. E.g.- Asia/Kolkata
start_date
string
Date from when the data is to be returned. E.g.- 2020-09-10
end_date
string
Date till when the data is to be returned. E.g.- 2020-09-13
page_number
integer
This field is used for getting 10 entries at a time. If the response returns an empty list in the data field, it is safe to assume the pages are exhausted.
If points_encoded value is true
, this value will not be considered.
E.g.- 1
Api-key
string
Auth-key E.g.- 33223kjhdcscijhb5sdbsdmjsdcbj5f
{
"status": true,
"msg": "Success.",
"code": 200,
"data": {
"next_page": null,
"pages": 1,
"prev_page": null,
"account_id": "60af304c51efb03cdde65042",
"users": [
{
"id": "60b90f1006f8a064fefae2f6",
"app_id": "60af306a8ce7db2392eb7a75_1",
"device_token": "d1_nRSCRgMI:APA91bFgVQ8BJqVJsuGF7CbFDfyiMSLgL6c0mW_GHVfeBcjEraRA6lJfreGqKSMzsvNE7ARJn-8V8_mbyL_Bwyy0ScKtjauarg84MyZlgRahszRVPr69-FgdvSx5xi699YGcXz8nfTnb",
"description": "tiiuhb",
"brand": "xiaomi",
"model": "Redmi Note 7",
"os_version": "28",
"sdk_version": "3.1.6",
"device_arn": "arn:aws:sns:us-east-1:218937252071:endpoint/GCM/app_60af306a8ce7db2392eb7a75_1_a678d41d-a66f-442b-90e5-1564b6c88c34/5b73758f-cc96-373a-a2dc-400d8c8f5685",
"geofence_events": true,
"motion_events": false,
"location_events": true,
"trips_events": true,
"nearby_events": true,
"location_listener": true,
"event_listener": true,
"is_deleted": false,
"created_at": "2021-06-03T17:19:12.287",
"last_location_update": {
"id": "60ba01c6498a3c7f94302f90",
"location_id": "60b9fffa1409b700002b0a84",
"coordinates": {
"type": "Point",
"coordinates": [
85.0689329,
25.6052153
]
},
"speed": 0.0,
"altitude": -10.53686590172557,
"activity": "MOVING",
"recorded_at": "2021-06-04T10:27:06.716",
"gps_status": true,
"battery_remaining": 59,
"app_context": "B",
"horizontal_accuracy": 68.4000015258789,
"vertical_accuracy": 3.0,
"location_permission": true,
"course": 241.92620849609375,
"source": "HTTPS",
"created_at": "2021-06-04T10:34:46.491"
}
},
{
"id": "60b90eea8ce7db0d651df5fe",
"app_id": "60af306a8ce7db2392eb7a75_1",
"device_token": "d1_nRSCRgMI:APA91bFgVQ8BJqVJsuGF7CbFDfyiMSLgL6c0mW_GHVfeBcjEraRA6lJfreGqKSMzsvNE7ARJn-8V8_mbyL_Bwyy0ScKtjauarg84MyZlgRahszRVPr69-FgdvSx5xi699YGcXz8nfTnb",
"description": "yyy",
"brand": "xiaomi",
"model": "Redmi Note 7",
"os_version": "28",
"sdk_version": "3.1.6",
"device_arn": "arn:aws:sns:us-east-1:218937252071:endpoint/GCM/app_60af306a8ce7db2392eb7a75_1_a678d41d-a66f-442b-90e5-1564b6c88c34/5b73758f-cc96-373a-a2dc-400d8c8f5685",
"geofence_events": true,
"motion_events": false,
"location_events": true,
"trips_events": true,
"nearby_events": true,
"location_listener": true,
"event_listener": true,
"is_deleted": false,
"created_at": "2021-06-03T17:18:34.128",
"last_location_update": {
"id": "60b90ef7c97ac210f948652c",
"location_id": "60b90ef456b5e30000c28d4d",
"coordinates": {
"type": "Point",
"coordinates": [
85.0693901,
25.6053019
]
},
"speed": 0.0,
"altitude": -10.436359168943534,
"activity": "MOVING",
"recorded_at": "2021-06-03T17:18:44.862",
"gps_status": true,
"battery_remaining": 75,
"app_context": "B",
"horizontal_accuracy": 12.505999565124512,
"vertical_accuracy": 3.0,
"location_permission": true,
"course": 104.81282806396484,
"source": "HTTPS",
"created_at": "2021-06-03T17:18:47.092"
}
},
{
"id": "60b90e9f8ce7db70981df5e8",
"app_id": "60af306a8ce7db2392eb7a75_1",
"device_token": "d1_nRSCRgMI:APA91bFgVQ8BJqVJsuGF7CbFDfyiMSLgL6c0mW_GHVfeBcjEraRA6lJfreGqKSMzsvNE7ARJn-8V8_mbyL_Bwyy0ScKtjauarg84MyZlgRahszRVPr69-FgdvSx5xi699YGcXz8nfTnb",
"description": "ttt",
"brand": "xiaomi",
"model": "Redmi Note 7",
"os_version": "28",
"sdk_version": "3.1.6",
"device_arn": "arn:aws:sns:us-east-1:218937252071:endpoint/GCM/app_60af306a8ce7db2392eb7a75_1_a678d41d-a66f-442b-90e5-1564b6c88c34/5b73758f-cc96-373a-a2dc-400d8c8f5685",
"geofence_events": true,
"motion_events": false,
"location_events": true,
"trips_events": true,
"nearby_events": true,
"location_listener": true,
"event_listener": true,
"is_deleted": false,
"created_at": "2021-06-03T17:17:19.612",
"last_location_update": {
"id": "60b90ee0c97ac210f94862d2",
"location_id": "60b90ed856b5e30000c28d4a",
"coordinates": {
"type": "Point",
"coordinates": [
85.0693876,
25.6053024
]
},
"speed": 0.0,
"altitude": -10.454078130984048,
"activity": "MOVING",
"recorded_at": "2021-06-03T17:18:16.317",
"gps_status": true,
"battery_remaining": 75,
"app_context": "B",
"horizontal_accuracy": 3.802000045776367,
"vertical_accuracy": 3.0,
"location_permission": true,
"course": 126.63764190673828,
"source": "HTTPS",
"created_at": "2021-06-03T17:18:24.413"
}
},
{
"id": "60b90e778ce7db0d651df5c1",
"app_id": "60af306a8ce7db2392eb7a75_1",
"device_token": "d1_nRSCRgMI:APA91bFgVQ8BJqVJsuGF7CbFDfyiMSLgL6c0mW_GHVfeBcjEraRA6lJfreGqKSMzsvNE7ARJn-8V8_mbyL_Bwyy0ScKtjauarg84MyZlgRahszRVPr69-FgdvSx5xi699YGcXz8nfTnb",
"description": "ravi",
"brand": "xiaomi",
"model": "Redmi Note 7",
"os_version": "28",
"sdk_version": "3.1.6",
"device_arn": "arn:aws:sns:us-east-1:218937252071:endpoint/GCM/app_60af306a8ce7db2392eb7a75_1_a678d41d-a66f-442b-90e5-1564b6c88c34/5b73758f-cc96-373a-a2dc-400d8c8f5685",
"geofence_events": true,
"motion_events": false,
"location_events": true,
"trips_events": true,
"nearby_events": true,
"location_listener": true,
"event_listener": true,
"is_deleted": false,
"created_at": "2021-06-03T17:16:39.652",
"last_location_update": {
"id": "60b90e8bc97ac210f9485a9c",
"location_id": "60b90e8856b5e30000c28d47",
"coordinates": {
"type": "Point",
"coordinates": [
85.069405,
25.6053002
]
},
"speed": 0.0,
"altitude": -10.697812527899808,
"activity": "MOVING",
"recorded_at": "2021-06-03T17:16:56.886",
"gps_status": true,
"battery_remaining": 75,
"app_context": "B",
"horizontal_accuracy": 13.935999870300293,
"vertical_accuracy": 3.0,
"location_permission": true,
"course": 289.4035949707031,
"source": "HTTPS",
"created_at": "2021-06-03T17:16:59.408"
}
},
{
"id": "60b90dd651efb070950db2e9",
"app_id": "60af306a8ce7db2392eb7a75_1",
"device_token": "d1_nRSCRgMI:APA91bFgVQ8BJqVJsuGF7CbFDfyiMSLgL6c0mW_GHVfeBcjEraRA6lJfreGqKSMzsvNE7ARJn-8V8_mbyL_Bwyy0ScKtjauarg84MyZlgRahszRVPr69-FgdvSx5xi699YGcXz8nfTnb",
"description": "raj",
"brand": "xiaomi",
"model": "Redmi Note 7",
"os_version": "28",
"sdk_version": "3.1.6",
"device_arn": "arn:aws:sns:us-east-1:218937252071:endpoint/GCM/app_60af306a8ce7db2392eb7a75_1_a678d41d-a66f-442b-90e5-1564b6c88c34/5b73758f-cc96-373a-a2dc-400d8c8f5685",
"geofence_events": true,
"motion_events": false,
"location_events": true,
"trips_events": true,
"nearby_events": true,
"location_listener": true,
"event_listener": true,
"is_deleted": false,
"created_at": "2021-06-03T17:13:58.830",
"last_location_update": {
"id": "60b90e2dc97ac210f94851b8",
"location_id": "60b90e2b56b5e30000c28d45",
"coordinates": {
"type": "Point",
"coordinates": [
85.0694115,
25.6053059
]
},
"speed": 0.0,
"altitude": -5.697860646978246,
"activity": "STOP",
"recorded_at": "2021-06-03T17:15:23.947",
"gps_status": true,
"battery_remaining": 75,
"app_context": "B",
"horizontal_accuracy": 28.729000091552734,
"vertical_accuracy": 7.07392692565918,
"location_permission": true,
"course": 39.287315368652344,
"source": "HTTPS",
"created_at": "2021-06-03T17:15:25.614"
}
},
{
"id": "60b90c688ce7db709c1df98a",
"app_id": "60af306a8ce7db2392eb7a75_1",
"device_token": "d1_nRSCRgMI:APA91bFgVQ8BJqVJsuGF7CbFDfyiMSLgL6c0mW_GHVfeBcjEraRA6lJfreGqKSMzsvNE7ARJn-8V8_mbyL_Bwyy0ScKtjauarg84MyZlgRahszRVPr69-FgdvSx5xi699YGcXz8nfTnb",
"description": "nikhil",
"brand": "xiaomi",
"model": "Redmi Note 7",
"os_version": "28",
"sdk_version": "3.1.6",
"device_arn": "arn:aws:sns:us-east-1:218937252071:endpoint/GCM/app_60af306a8ce7db2392eb7a75_1_a678d41d-a66f-442b-90e5-1564b6c88c34/5b73758f-cc96-373a-a2dc-400d8c8f5685",
"geofence_events": true,
"motion_events": false,
"location_events": true,
"trips_events": true,
"nearby_events": true,
"location_listener": true,
"event_listener": true,
"is_deleted": false,
"created_at": "2021-06-03T17:07:52.086",
"last_location_update": {
"id": "60b90dd2a742058ec1fa4de1",
"location_id": "60b90dce56b5e30000c28d42",
"coordinates": {
"type": "Point",
"coordinates": [
85.0693941,
25.6053027
]
},
"speed": 0.0,
"altitude": -10.587453258919219,
"activity": "MOVING",
"recorded_at": "2021-06-03T17:13:50.867",
"gps_status": true,
"battery_remaining": 75,
"app_context": "B",
"horizontal_accuracy": 4.288000106811523,
"vertical_accuracy": 3.0,
"location_permission": true,
"course": 121.61729431152344,
"source": "HTTPS",
"created_at": "2021-06-03T17:13:54.377"
}
},
{
"id": "60b89cd706f8a06fb1fae098",
"app_id": "60af306a8ce7db2392eb7a75_1",
"device_token": "cyv7qo-5XDw:APA91bGFPNoHCmY26ckS34g4qze0Y6J6EQPNq2fsQyStd4oU6-dZTKjJ5PvxWEGtHFl6YVpk5wbBgXBbsNzCcG4uwWfhMCFtw3zT5n2NgBEL55XwVE0gmfx7CprmJkZCZDi3mbl_9kcW",
"device_uuid": "03611b89-b17a-4c75-bde1-86f7411df774",
"description": "ram",
"brand": "xiaomi",
"model": "Redmi Note 7",
"os_version": "28",
"sdk_version": "3.1.3",
"device_arn": "arn:aws:sns:us-east-1:218937252071:endpoint/GCM/app_60af306a8ce7db2392eb7a75_1_a678d41d-a66f-442b-90e5-1564b6c88c34/81c4df96-3e2e-3592-a9a7-fd96e1092d1f",
"geofence_events": true,
"motion_events": false,
"location_events": true,
"trips_events": true,
"nearby_events": true,
"location_listener": true,
"event_listener": true,
"is_deleted": false,
"created_at": "2021-06-03T09:11:51.516",
"last_location_update": {
"id": "60b90c03a742058ec1fa1d2c",
"location_id": "60b90c0156b5e30000628b90",
"coordinates": {
"type": "Point",
"coordinates": [
85.0693781,
25.6053302
]
},
"speed": 3.0,
"altitude": -10.6220032343052,
"activity": "MOVING",
"recorded_at": "2021-06-03T17:06:09.865",
"gps_status": false,
"battery_remaining": 77,
"app_context": "B",
"horizontal_accuracy": 9.64799976348877,
"vertical_accuracy": 3.0,
"location_permission": true,
"course": 11.085373878479004,
"source": "HTTPS",
"created_at": "2021-06-03T17:06:11.106"
}
},
{
"id": "60b89cb306f8a06fb3fae0a8",
"app_id": "60af306a8ce7db2392eb7a75_1",
"device_token": "cyv7qo-5XDw:APA91bGFPNoHCmY26ckS34g4qze0Y6J6EQPNq2fsQyStd4oU6-dZTKjJ5PvxWEGtHFl6YVpk5wbBgXBbsNzCcG4uwWfhMCFtw3zT5n2NgBEL55XwVE0gmfx7CprmJkZCZDi3mbl_9kcW",
"description": "raju",
"brand": "xiaomi",
"model": "Redmi Note 7",
"os_version": "28",
"sdk_version": "3.1.3",
"device_arn": "arn:aws:sns:us-east-1:218937252071:endpoint/GCM/app_60af306a8ce7db2392eb7a75_1_a678d41d-a66f-442b-90e5-1564b6c88c34/81c4df96-3e2e-3592-a9a7-fd96e1092d1f",
"geofence_events": true,
"motion_events": false,
"location_events": true,
"trips_events": true,
"nearby_events": true,
"location_listener": true,
"event_listener": true,
"is_deleted": false,
"created_at": "2021-06-03T09:11:15.569",
"last_location_update": {
"id": "60b89cbd738eafe5bb7feef7",
"location_id": "60b89cb64319ec000069d0a8",
"coordinates": {
"type": "Point",
"coordinates": [
85.0693555,
25.6054544
]
},
"speed": 0.0,
"altitude": -10.98783069403458,
"activity": "MOVING",
"recorded_at": "2021-06-03T09:11:18.960",
"gps_status": true,
"battery_remaining": 87,
"app_context": "F",
"horizontal_accuracy": 34.400001525878906,
"vertical_accuracy": 3.0,
"location_permission": true,
"course": 0.0,
"source": "HTTPS",
"created_at": "2021-06-03T09:11:25.465"
}
}
]
}
}
curl --location --request GET 'https://api.roam.ai/v1/api/user/?start_date=2021-06-01&end_date=2021-06-06' \
--header 'Api-Key: 761f129e9d3a4de380baa6f4f0e7ab05'
The Roam iOS SDK makes it quick and easy to build a location tracker for your iOS app. We provide powerful and customizable tracking modes and features that can be used to collect your users’ location
To use the Roam SDK, the following things are required:
Get yourself a free . No credit card required.
Create a project and add an iOS app to the project.
You need the SDK_KEY (available in your project settings) to initialize the SDK.
You’re now ready to integrate the SDK into your iOS application.
The Roam iOS SDK requires Xcode 10.0 or later and is compatible with apps targeting iOS version 10 and above.
The Roam Example repository on includes example apps that demonstrate the use of the v3 Roam SDK for iOS.
See Swift's example app in Example/
.
To run an example app, clone this repository, add your publishable YOUR-PUBLISHABLE-KEY
key in AppDelegate.swift
, and build the app.
Make sure the bundle_id is the same as the one registered on our Roam Playground dashboard.
To integrate the Roam SDK, you need a Roam account.
Go to Xcode > File > New Project
Configure the information property list file Info.plist
with an XML snippet that contains data about your app. You need to add strings for NSLocationWhenInUseUsageDescription
in the Info.plist
file to prompt the user during location permissions for foreground location tracking. For background location tracking, you also need to add a string for NSLocationAlwaysUsageDescription
and NSLocationAlwaysAndWhenInUseUsageDescription
in the same Info.plist
file.
Next, you need to enableBackground fetch
and Location updates
under Project Setting
> Capabilities
> Background Modes
.
There are several ways to integrate the Roam Mobile SDK for iOS into your own project:
Swift Package Manager
CocoaPods
Carthage (Will be added soon)
Dynamic Frameworks
Swift Package Manager is distributed with Xcode. To start adding the AWS SDK to your iOS project, open your project in Xcode and select File > Swift Packages > Add Package Dependency.
Enter the URL for the Roam SDK for iOS Swift Package Manager GitHub repo () into the search bar and click Next.
You'll see the repository rules for which version of the SDK you want the Swift Package Manager to install. Choose the first rule, Version, and select Up to Next Minor as it will use the latest compatible version of the dependency that can be detected from the main branch, then click Next.
Select roam-ios
, then click Finish.
You can always go back and modify which SPM packages are included in your project by opening the Swift Packages tab for your project: Click on the Project file in the Xcode navigator, then click on your project's icon, then select the Swift Packages tab.
Follow the steps below to add the SDK to the project using CocoaPods. Add the below to the Podfile
Then run pod install
.
This will add the Roam SDK and its dependencies to your project. The Roam SDK depends on CoreLocation
, AWSMobileClient
and AWSIoT
for fetching locations and its transmission to our servers. The SDK supports iOS 10 and above.
If you’re not familiar with using Cocoapods or prefer manual installation, we’ve added a ZIP file to the SDK. Use this link to download the file.
Unzip the file and add the Roam Roam.framework
to your Xcode project by dragging the file into your Project Navigator.
You can do this by selecting the project file in the navigator on the left side of the Xcode window, and then navigating to the Linked Frameworks and Libraries section. From there, click the “+” button to add the Roam framework. You will also want to add the following frameworks from this .
Make sure the the added frameworks under Linked Frameworks and Libraries section are selected as Embed & Sign
Roam SDK offers a flexible method of initialization, allowing developers to seamlessly integrate our services into their applications. With our latest update, we've introduced a new initialization approach using property list files (plist). This method provides an effortless way to set up your Roam SDK without the need for additional code.
Using Property List (plist) Initialization:
Optional Parameter: Publish Key
The publishKey
parameter in the initialization method is now optional.
If you've added your Roam publish key to your project's .plist
file, there's no need to pass the publishKey
parameter during initialization.
Configure Your .plist File:
In your info.plist
file, declare your Roam publish key as follows:
Replace "$(ROAM_PUBLISH_KEY)"
with your actual Roam publish key.
Using XCConfig File (Optional):
Alternatively, you can use an XCConfig file to feed the Roam publish key to the plist file.
In your XCConfig file, add the following line, replacing XXXXXXXXXXXXXX
with your Roam publish key:
Initialization Code:
Initialize Roam SDK in your application as follows:
If the publish key is added to the plist, the initialize
method can be called without passing any parameters.
By following these steps, you can seamlessly initialize Roam SDK using property list files, simplifying the integration process and saving valuable development time.
Using AppDelegate Initialization:
Add the following code to AppDelegate
file. This code imports the SDK and allows the SDK to use other methods.
After import, add the below code underapplication(_:didFinishLaunchingWithOptions:)
in your AppDelegate
file. The SDK must be initialized before calling any of the other SDK methods using your project's publishable key.
Before you start location tracking, you need to get permission from the user for your application to access locations.
Import CoreLocation
at the top of the AppDelegate
file.
Make the below class declaration for Location Manager and add this line before the return statement in application(_:didFinishLaunchingWithOptions:)
With this line, you ask users to allow the app to access location data both in the background and the foreground.
Use one of the tracking modes while you use the Roam.startTracking
method.
To stop the tracking use the below method.
Roam has three default tracking modes along with a custom version. They are different based on the frequency of location updates and battery consumption. The higher the frequency, the higher the battery consumption.
The SDK also provides a custom tracking mode which allows you to customize and build your own tracking mode as per your requirement.
Distance between location updates example code:
Time between location updates example code:
To listen to location updates, create a class that implements RoamDeleagate and then call Roam.delegate.
Set your RoamDeleagate in a code path that will be initialized and executed in the background. For example, make your AppDelegate implement RoamDeleagate, not a ViewController. AppDelegate will be initialized in the background, whereas a ViewController may not be.
Batch configuration lets you control the number of location data updates being received in the location listener with the desired frequency and window.
As the name suggests, this method sets the configuration parameters.
The networkState
indicates the state in which the updates are to be received. It can either be set to online, offline, or both.
The batchCount
indicates the size of the location batch.
The batchWindow
indicates the time interval for every consecutive update (frequency of updates).
Consider the following call,
Roam.setBatchConfig("
networkState.Both", 5 , 60)
The batch count value is the number of location updates sent in a batch. In the above case, the value is set to 5. Ideally, the SDK sends 5 updates per batch and the batch window (in the above case, 60) specifies the number of seconds the SDK waits to receive five location updates.
If the SDK receives 5 location updates in less than 60 seconds, the updates are pushed to the listener. If not, it waits for 60 seconds and pushes the location updates regardless of the batch count value.
Success Callback - We receive a list of BatchReceiveConfig objects.
Example response:
[{"batchCount":5,"batchWindow":10,"networkState":"offline"}, {"batchCount":5,"batchWindow":10,"networkState":"online"}]
Error Callback: We receive a RoamError object in the error callback.
The available details to get from the RoamError object are: error.getMessage() and error.getCode()
The get receiver config method allows the user to get the current batch configuration for the location listener.
The Reset Batch Configuration method allows the user to reset the batch config for the location listener.
Explore how to publish and subscribe locations for iOS.
User sessions are mandatory for pub/sub tracking. Without user sessions, location tracking will continue to work as self tracking and pub/sub methods will return error callbacks.
Once the SDK is initialized, you need to create or get a user to start the tracking and use other methods. Each user created will have a unique Roam identifier which will be used to login and access developer APIs. We call this the Roam user_Id
.
The "user description" option can be used to update user information such as name, address or add an existing user ID. Make sure the information is encrypted if you are planning to save personal information like an email ID or phone number.
You can always set or update user descriptions and meta-data later using the code below.
If you already have a Roam user_ID
that you would like to reuse instead of creating a new user, use the code below to get a user session.
Location data will be published and sent to the Roam servers for further processing. The data will be saved on our database servers.
To stop publishing the location data to other clients.
Now that you have enabled the location listener, use the below method to subscribe to your own or other user's location updates and events.
You can pass an emptyuser_id
which is an optional field from v0.0.16 to unsubscribe from all users.
Listeners are needed to consume the location or event data from the SDK.
In order to enable listeners, the following must be ensured.
Before adding listeners for locations and other data, we need to toggle the listener flags for the user in order to get the data.
To do that, you need to toggle the location and event listener to true
. By default, the status will be set to false
and needs to be set to true
in order to stream the location and event updates to the same device or other devices.
You can also get the current status of listeners with this method.
To listen to events on the server-side, you should enable events for the user using the below method.
Set your RoamDelegate
in a code path that will be initialized and executed in the background. For example, ensure that your AppDelegate
and not the ViewController
implements RoamDelegate
. The reason being, AppDelegate
will be initialized in the background, whereas a ViewController
may not be.
// create user with meta-data and description
// Declare meta-data as dictionary
// Description as string
let metaData:Dictionary<String,Any> = ["key":value]
Roam.createUser("YOUR-USER-DESCRIPTION-GOES-HERE", metaData) {(RoamUser, Error) in
// Access Roam user data below
// RoamUser?.userId
// RoamUser?.description
// RoamUser?.locationListener
// RoamUser?.eventsListener
// RoamUser?.locationEvents
// RoamUser?.geofenceEvents
// RoamUser?.tripsEvents
// RoamUser?.nearbyEvents
// RoamUser?.metaData
// Access the error code & message below
// Error?.code
// Error?.message
}
// update user with meta-data and description
// Declare meta-data as dictionary
// Description as string
let metaData:Dictionary<String,Any> = ["key":value]
Roam.updateUser("Description", metaData)
// update user with meta-data and description
// Declare meta-data as dictionary
// Description as string
[Roam updateUser:@"userDescription" :@"metadata"];
Roam.getUser("YOUR-ROAM-USER-ID") {(RoamUser, Error) in
// Access Roam user data below
// RoamUser?.userId
// RoamUser?.description
// RoamUser?.locationListener
// RoamUser?.eventsListener
// RoamUser?.locationEvents
// RoamUser?.geofenceEvents
// RoamUser?.tripsEvents
// RoamUser?.nearbyEvents
// Access error code & message below
// Error?.code
// Error?.message
}
let metaData:Dictionary<String,Any> = ["key":"value"]
let locationData = RoamPublish()
locationData.meta_data = metaData
Roam.publishSave(locationData){ status, error in
}
Roam.stopPublishing(){ status, error in
};
Roam.subscribe(TYPE, "ROAM-USER-ID"){ status, userId, error in
};
Roam.unSubscribe(TYPE, "ROAM-USER-ID"){ status, userId, error in
};
Type
Description
RoamSubscribe.Events
Subscribe to your own events.
RoamSubscribe.Location
Subscribe to your own location (or) other user's location updates.
RoamSubscribe.Both
Subscribe to your own events and location (or) other user location updates.
Roam.toggleListener(Events: true, Locations: true) {(RoamUser, Error) in
// Access Roam user data below
// RoamUser?.userId
// RoamUser?.description
// RoamUser?.locationListener
// RoamUser?.eventsListener
// RoamUser?.locationEvents
// RoamUser?.geofenceEvents
// RoamUser?.tripsEvents
// RoamUser?.nearbyEvents
// Access error code & message below
// Error?.code
// Error?.message
}
Roam.getListenerStatus() {(RoamUser, Error) in
// Access Roam user data below
// RoamUser?.userId
// RoamUser?.description
// RoamUser?.locationListener
// RoamUser?.eventsListener
// RoamUser?.locationEvents
// RoamUser?.geofenceEvents
// RoamUser?.tripsEvents
// RoamUser?.nearbyEvents
// Access error code & message below
// Error?.code
// Error?.message
}
Roam.toggleEvents(Geofence: true, Location: true, Trips: true, MovingGeofence: true { (RoamUser, Error) in
// Access Roam user data below
// RoamUser?.userId
// RoamUser?.description
// RoamUser?.locationListener
// RoamUser?.eventsListener
// RoamUser?.locationEvents
// RoamUser?.geofenceEvents
// RoamUser?.tripsEvents
// RoamUser?.nearbyEvents
// Access error code & message below
// Error?.code
// Error?.message
}
Once the listener toggles are set to true, to listen to location updates, create a class that implements RoamDelegate and then call Roam.delegate.
import UIKit
import Roam
import CoreLocation
@main
class AppDelegate: UIResponder, UIApplicationDelegate, RoamDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Roam.delegate = self
Roam.initialize("YOUR-SDK-KEY-GOES-HERE")
return true
}
func didUpdateLocation(_ location: RoamLocation) {
// Do something with the user location
// location.userId
// location.activity
// location.timezoneOffset
// location.recordedAt
// location.batteryRemaining
// location.networkStatus
// location.metaData
// location.location.speed
// location.location.horizontalAccuracy
// location.location.verticalAccuracy
// location.location.altitude
// location.location.course
// location.location.coordinate.latitude
// location.location.coordinate.longitude
}
func didReceiveEvents(_ events: RoamEvents) {
// Do something with user events
}
func didReceiveUserLocation(_ location: RoamLocationReceived) {
// Do something with other users' subscribed location
}
func didReceiveTripStatus(_ tripStatus: [RoamTripStatusListener]) {
//do something with trip status data
}
}
Keep yourself updated on any iOS changes.
We're pleased to announce Roam iOS SDK version 0.1.19, primarily focused on resolving issues related to crashes occurring with Core Data and AWS IoT during location tracking in the background state and other rare scenarios. In this update, we've made the following fixes:
Core Data and AWS-IoT Crash Fixes: Addressed crashes occurring during location tracking in the background state and other infrequent scenarios related to Core Data and AWS IoT integrations. Users can now expect improved stability and reliability when utilizing these features.
These fixes aim to enhance the overall stability of the SDK, ensuring a smoother experience for developers and users alike. We're committed to providing a robust and dependable SDK. If you encounter any further issues or have feedback to share, please reach out to our support team. We're here to assist you promptly.
We're excited to introduce Roam iOS SDK version 0.1.18, focusing on enhancing our network module and refining tracking logics. In this update, we've made the following improvements:
Enhanced Connectivity during Location Tracking: We've revamped the network module to handle few edge-cases on connectivity during location tracking. Expect smoother and more reliable communication between your app and Roam's services, ensuring a seamless experience for users even in challenging network conditions.
Minor Improvements to Tracking Logics: We've implemented minor refinements to our tracking logics. These subtle enhancements aim to fine-tune the tracking mechanisms, resulting in improved accuracy and efficiency when capturing and processing location data.
These improvements are geared towards providing a more robust and consistent experience for developers and users alike. We're dedicated to optimizing your tracking capabilities and ensuring a smoother operational experience. Should you have any inquiries or feedback, our support team is readily available to assist you.
We're thrilled to present Roam iOS SDK version 0.1.17, focusing on bolstering our security module. In this update, we've made significant improvements to enhance the security of location data. Here's what's new:
Efficient Spoofed Location Detection: Our security algorithm has been refined to efficiently discard spoofed locations during the initial location fix. This enhancement ensures that only genuine and accurate location data is captured, enhancing the authenticity of the information gathered.
Addressing False Negatives: We've tackled false negatives during location tracking, ensuring that true locations are not mistakenly identified as spoofed locations. This refinement enhances the precision of location tracking, providing you with reliable and accurate data.
These security enhancements are designed to safeguard your data and ensure the integrity of the location information collected by the Roam iOS SDK. Your security is our priority, and we're committed to providing you with a secure and trustworthy experience. If you have any questions, concerns, or feedback, our support team is always here to assist you.
We're excited to introduce Roam iOS SDK version 0.1.16, focusing on refining connectivity and enhancing tracking performance. In this update, we've made the following improvements:
Enhanced Connectivity: We've optimized the SDK's connectivity, ensuring smoother communication between your app and Roam's services. This enhancement leads to a more stable and reliable connection experience.
Improved Tracking Performance: Our team has worked diligently to enhance the overall tracking performance of the Roam iOS SDK. Expect better accuracy, responsiveness, and efficiency when tracking user data, providing a seamless experience for your users.
These improvements are designed to elevate your tracking capabilities and provide a more robust experience for both you and your users. As always, your feedback is invaluable to us. For any inquiries, support, or to share your feedback, don't hesitate to reach out to our dedicated support team. We're here to assist you every step of the way.
We're thrilled to announce the release of Roam iOS SDK version 0.1.15, bringing powerful enhancements and simplified integration. Here's what's new:
Callback Integration: We've added callbacks to essential methods like startTracking
, stopTracking
, subscribe
, unSubscribe
, publishAndSave
, and stopPublishing
. These callbacks provide clear onSuccess
and onError
methods, ensuring you have complete control and real-time feedback for every SDK action.
Simplified Initialization: Now, initializing the Roam SDK is easier than ever. Simply place your publishable key in the .plist
file, streamlining the setup process and getting you up and running swiftly.
Your feedback has been invaluable in shaping these improvements. For any queries, assistance, or to share your experiences, our support team is here to help.
We're excited to announce the latest release of the Roam iOS SDK version 0.1.14. This update brings a significant enhancement that contributes to heightened security and user control. Read on to discover the key highlights of this release:
New Feature: Motion Detection Security With Roam iOS SDK v0.1.14, we introduce an innovative security feature—Motion Detection. This cutting-edge capability adds an extra layer of protection to your application's tracking experience. By enabling the verifyMotion parameter in the toggleSecurity() method, developers can now leverage motion patterns to enhance security. This empowers you to monitor and respond to unusual motion activities, ensuring a safer and more reliable tracking environment. As always, we appreciate your feedback and contributions in helping us refine and enhance the Roam iOS SDK. Please feel free to reach out to our support team if you have any questions, concerns, or suggestions. Stay tuned for more updates as we continue to improve the SDK's capabilities and features.
We're excited to introduce Roam iOS SDK version 0.1.13, which includes a significant enhancement aimed at strengthening security within the SDK. Here's a breakdown of the latest changes:
New Security Module: Roam We've incorporated an advanced security module named Roam into the SDK. With this release, developers can take advantage of the toggleSecurity() method provided by Roam. This addition allows for seamless enabling and disabling of enhanced security measures. Protecting sensitive data is of paramount importance, and the Roam security module provides a streamlined way to fortify your application's defenses. As always, we appreciate your feedback and contributions in helping us refine and enhance the Roam iOS SDK. Please feel free to reach out to our support team if you have any questions, concerns, or suggestions. Stay tuned for more updates as we continue to improve the SDK's capabilities and features.
Fixed the tracking issue during terminated state for SDK only tracking.
Fixed multiple users creating when calling setDeviceToken
method.
Added few support for new error codes and messages in on didError
delegate.
Fixed a number of crashes that occurred while tracking in specific scenarios, improving the overall stability of the SDK.
Cleared console warnings to improve the developer experience.
Improved user subscription process for a smoother and more streamlined experience.
Improved location tracking logic to improve the accuracy and reliability of the SDK.
Overall performance and stability of the SDK have been improved.
Activity recognition permission issues fixed.
In this release, we have made the following improvements to enhance the user experience of our Roam iOS SDK:
Activity recognition methods: We have added activity recognition methods to the Roam iOS SDK to provide a more accurate and reliable determination of the user's current activity. This will improve the accuracy of location tracking, especially when the user is in motion.
Improved tracking logic: To further improve battery consumption, we have made some changes to our tracking logic. These changes are aimed at ensuring that the Roam SDK is as efficient as possible in terms of energy usage, while still providing accurate location tracking. We are confident that these changes will improve the overall experience of our Roam iOS SDK and we hope you enjoy these enhancements. If you have any questions or concerns, please feel free to reach out to us.
We're excited to introduce Roam iOS SDK version 0.1.13, which includes a significant enhancement aimed at strengthening security within the SDK. Here's a breakdown of the latest changes:
New Security Module: Roam
We've incorporated an advanced security module named Roam into the SDK. With this release, developers can take advantage of the toggleSecurity()
method provided by Roam. This addition allows for seamless enabling and disabling of enhanced security measures. Protecting sensitive data is of paramount importance, and the Roam security module provides a streamlined way to fortify your application's defences.
As always, we appreciate your feedback and contributions in helping us refine and enhance the Roam iOS SDK. Please feel free to reach out to our support team if you have any questions, concerns, or suggestions. Stay tuned for more updates as we continue to improve the SDK's capabilities and features.
Fixed the tracking issue during terminated state for SDK only tracking.
Fixed mutiple users creating when calling setDeviceToken
method.
Added a few support for new error codes and messages on the didError
delegate.
Fixed a number of crashes that occurred while tracking in specific scenarios, improving the overall stability of the SDK.
Cleared console warnings to improve the developer experience.
Improved user subscription process for a smoother and more streamlined experience.
Improved location tracking logic to improve the accuracy and reliability of the SDK.
Overall performance and stability of the SDK have been improved.
Activity recognition permission issue fixed.
In this release, we have made the following improvements to enhance the user experience of our Roam iOS SDK:
Activity recognition methods: We have added activity recognition methods to the Roam iOS SDK to provide a more accurate and reliable determination of the user's current activity. This will improve the accuracy of location tracking, especially when the user is in motion.
Improved tracking logic: To further improve battery consumption, we have made some changes to our tracking logic. These changes are aimed at ensuring that the Roam SDK is as efficient as possible in terms of energy usage, while still providing accurate location tracking.
We are confident that these changes will improve the overall experience of our Roam iOS SDK and we hope you enjoy these enhancements. If you have any questions or concerns, please feel free to reach out to us.
Tweaked the tracking algorithm for efficient battery consumption: We have made changes to our tracking algorithm to optimize battery consumption. The new algorithm is designed to reduce battery usage while maintaining the same level of accuracy and reliability.
Added basic ingest publish topic for AWS cost optimization.
Fixed drift issue for distance-based tracking.
Fixed drift issue for distance-based tracking.
Fixed total elevation issue in sync trip.
Added:
Added elevation gain parameter to trip listener.
Added speed parameter to location listener.
Fixed:
Location calibration when used along with accuracy config and time-based tracking.
Tracking config issue for time-based tracking.
Fixed crash when user received other user location.
Removed blue bar on user logout without stop tracking.
Fixed distance calculation logic for individual route points in RoamTripsSummary.
Added a new Roam.requestAlwaysAuthorization()
method for location permission control.
Making SDK backwards compatible to support Xcode 13.X with Swift v5.6.1.
Location calibration when used along with accuracy config and time-based tracking.
Added elevation gain parameter to trip listener.
Added speed parameter to location listener.
Added support for Roam.initialize() with custom configurations.
Made the SDK backwards compatible to support Xcode 14.x with Swift v5.7 along with the fix for crash issues while receiving other user locations.
Made the SDK backwards compatible to support Xcode 13.x with Swift v5.6.1 along with the fix for the crash issues while receiving other user locations.
Tracking config issue for time-based tracking.
Fixed crash when user received other user location.
Removed blue bar on user logout without stopping tracking.
Added:
Added accuracy config methods for Roam.getCurrentLocation()
, Roam.updateCurrentLocation()
and Time based custom tracking.
Added timestamps to the trip listener data.
Added option to unsubscribe from all the trips in the method Roam.unsubscribeTripStatus()
Added new methods for batch configurations in trips data receiver.
Trips data in a trip receiver is changed from a single object to a list of updates.
Added new methods for batch configurations in location receiver.
Fixed:
Fixed crashing behavior while changing location permission.
Fixed blue bar issue for custom tracking modes.
Fixed location tracking issue when location permission is changed.
The fixed trip listener works independently of the location listener.
Fixes core data for location and trips.
Fixed:
Crash when Roam.getTrip()
is called without starting the trip.
Modified:
Removed user id validation for offline trips.
Create trip without user id. ie. optional
Support to update trip based on trip state.
Added:
Speed parameter to the routes in the trips summary.
Subscribe to online trips.
Modified:
Updated new trip v2 methods. Refer Migration guide for more details.
Fixed:
Fixed distance calculation logic for individual route points in RoamTripsSummary
.
Fixed:
Fixed crashing behavior while changing location permission.
Fixed:
Fixed build issues with v0.0.26.
Added:
Added accuracy config methods for Roam.getCurrentLocation()
, Roam.updateCurrentLocation()
and Time based custom tracking.
Fixed:
Fixed blue bar issue for custom tracking modes.
Fixed location tracking issue when location permission is changed.
Fixes:
Added:
Added timestamps to the trip listener data.
Created option to unsubscribe from all the trips in the method Roam.unsubscribeTripStatus().
The fixed trip listener works independently of the location listener.
Added:
Added new methods for batch configurations in trips data receiver.
Trip data in a trip receiver is changed from a single object to a list of updates.
Fixed:
Fixes core data for location and trips.
Added:
Added callbacks to Roam.resetBatchReceiverConfig
method to return default config values.
Added:
Added new methods for batch configurations in location receiver.
Updated trip error codes.
Fixed:
Fixed calculation for distance and duration for individual location data in trip summary route.
Added:
Added individual distance, duration, and elevation gain for location data inside trip routes for local trips.
Trip summary response for the local trip will have the route sorted by recorded timestamp.
Fixed:
Fixed background location tracking for time-based tracking mode when location permission is given as 'Allow while using'
Fixed:
Fixed the coordinates arrangement for Roam.getTripSummary()
on local trips.
Fixed:
Removed the blue bar that was being displayed during active tracking.
Modified:
Added an option in Roam.unSubscribe()
which will now unsubscribe all users if user_id
is passed as null or empty.
Added battery and network details as part of the location in the location receiver.
Fixed:
Issues in tracking location when the application is forced to terminate by the user. The SDK will now restart the tracking automatically.
Fixed:
Improved Roam.getCurrentLocation()
to return the location faster.
Fixed:
Location activity was getting updated as stationary for all location points during the terminated state.
Modified:
Custom tracking options will now work in the terminated state. (SDK will wait for a significant change in the device location to restart the tracking again in the background)
Added:
Support to listen to location updates of users from different projects which are in the same account.
Fixed:
Multiple location updates are recorded when the user is stationary while tracking.
Modified:
#28 Made startTrip
independent by combining it with startTracking
and createTrip
methods
Added:
metadata
support for users and trips were added
Modified:
#19 Allowed meta-data
support for updating location, i.e., updateCurrentLocation
method.
Removed:
#20 Combined startTracking
and startSelfTracking
methods.
Added:
#21 Updated location when a user becomes stationary.
Fixed #23 - Tracking stops working after new getUser()
or createUser()
session
#13 In order to support Apple Silicon M1 Macs, we added arm64 to iOS simulator builds.
#5 Added support for XCFrameworks
#4 Added support for Swift Package Manager
#11 Updated the docs to support the SPM integration steps
Updated dependency frameworks for XCFramworks to avoid build issues during manual integration.
Refactored the current framework to support dependencies from local XCFrameworks.
Added the total elevation gain parameter to the already existing elevation gain, distance, and duration parameters in the trip summary.
Added support new compiler version for Xcode 12.5.1 with Swift v5.4.2
Added:
isTripSync() Method
Fixed:
Fixed Location Id generation for Offline Trips
Modified:
Replaced AWSIOT with CocoaMQTT
The first version of Roam iOS SDK
<key>NSLocationWhenInUseUsageDescription</key>
<string>Add description for foreground only location usage.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Add description for background location usage. iOS 10 and below"</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Add description for background location usage. iOS 11 and above</string>
pod 'roam-ios'
AWSAuthCore.xcframework
AWSCognitoIdentityProvider.xcframework
AWSCognitoIdentityProviderASF.xcframework
AWSCore.xcframework
AWSIoT.xcframework
AWSMobileClientXCF.xcframework
<key>ROAM_PUBLISH_KEY</key>
<string>$(ROAM_PUBLISH_KEY)</string>
ROAM_PUBLISH_KEY = XXXXXXXXXXXXXX
Roam.initialize("")
// OR
Roam.initialize(nil)
import Roam
Roam.initialize("YOUR-SDK-KEY-GOES-HERE")
import CoreLocation
let locationManager = CLLocationManager()
locationManager.requestLocation()
Roam.startTracking(TrackingMode){ status, error in
}
Roam.stopTracking(){ status, error in
}
Mode
Battery usage
Updates every
Optimised for/advised for
Active
6% - 12%
25 ~ 250 meters
Ride Hailing / Sharing
Balanced
3% - 6%
50 ~ 500 meters
On Demand Services
Passive
0% - 1%
100 ~ 1000 meters
Social Apps
//active tracking
Roam.startTracking(RoamTrackingMode.active){ status, error in
}
// balanced tracking
Roam.startTracking(RoamTrackingMode.balanced){ status, error in
}
// passive tracking
Roam.startTracking(RoamTrackingMode.passive){ status, error in
}
Type
Unit
Unit Range
Distance Interval
Meters
1m ~ 2500m
// Define a custom tracking method
let distanceTrackingMethod = RoamTrackingCustomMethods()
// Update the settings for the created method as per need
distanceTrackingMethod.activityType = .fitness
distanceTrackingMethod.pausesLocationUpdatesAutomatically = true
distanceTrackingMethod.showsBackgroundLocationIndicator = true
distanceTrackingMethod.useSignificant = false
distanceTrackingMethod.useRegionMonitoring = false
distanceTrackingMethod.useVisits = false
distanceTrackingMethod.accuracyFilter = 10
distanceTrackingMethod.desiredAccuracy = .kCLLocationAccuracyNearestTenMeters
// Update the distance intervel as per the use case in meters
distanceTrackingMethod.distanceFilter = 10
// Start the tracking with the above created custom tracking method
Roam.startTracking(.custom, options: distanceTrackingMethod){ status, error in
}
Type
Unit
Unit Range
Time Interval
seconds
1s - 10000s
// Define a custom tracking method
let timeTrackingMethod = RoamTrackingCustomMethods()
// Update the settings for the created method as per need
timeTrackingMethod.activityType = .fitness
timeTrackingMethod.pausesLocationUpdatesAutomatically = true
timeTrackingMethod.showsBackgroundLocationIndicator = true
timeTrackingMethod.useSignificant = false
timeTrackingMethod.useRegionMonitoring = false
timeTrackingMethod.useVisits = false
timeTrackingMethod.accuracyFilter = 10
timeTrackingMethod.desiredAccuracy = .kCLLocationAccuracyNearestTenMeters
// Update the time intervel as per the use case in seconds
timeTrackingMethod.updateInterval = 10
// Start the tracking with the above created custom tracking method
Roam.startTracking(.custom, options: timeTrackingMethod){ status, error in
}
import UIKit
import Roam
import CoreLocation
@main
class AppDelegate: UIResponder, UIApplicationDelegate, RoamDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Roam.delegate = self
Roam.initialize("YOUR-SDK-KEY-GOES-HERE")
return true
}
func didUpdateLocation(_ location: RoamLocation) {
// Do something with the user location
// location.userId
// location.activity
// location.timezoneOffset
// location.recordedAt
// location.batteryRemaining
// location.networkStatus
// location.metaData
// location.location.speed
// location.location.horizontalAccuracy
// location.location.verticalAccuracy
// location.location.altitude
// location.location.course
// location.location.coordinate.latitude
// location.location.coordinate.longitude
}
// let networkState:RoamNetworkState = .Both
// batchCount: number of location updated
// batchWindow : frequency of location updates.
Roam.setBatchReceiverConfig(networkState: networkState, batchCount: batchCount,
batchWindow: batchWindow) { config, error in
// error?.code
// error?.message
// config?.batchCount
// config?.batchWindow
// config?.networkState
}
[Roam setBatchReceiverConfigWithNetworkState: networkState batchCount:batchCount
batchWindow:batchWindow handler:^(RoamBatchConfig * config, RoamError * error) {
// error?.code
// error?.message
// config?.batchCount
// config?.batchWindow
// config?.networkState
}];
Roam.getBatchReceiverConfig { config, error in
// error?.code
// error?.message
// config?.batchCount
// config?.batchWindow
// config?.networkState
}swif
[Roam getBatchReceiverConfigWithHandler:^(RoamBatchConfig * config, RoamError * error)
{
// error?.code
// error?.message
// config?.batchCount
// config?.batchWindow
// config?.networkState
}];
obj
Roam.resetBatchReceiverConfig { config, error in
// error?.code
// error?.message
// config?.batchCount
// config?.batchWindow
// config?.networkState
}
[Roam resetBatchReceiverConfigHandler:^(RoamBatchConfig * config, RoamError * error)
{
// error?.code
// error?.message
// config?.batchCount
// config?.batchWindow
// config?.networkState
}];
Explore Roam's Trips documentation.
Trips allow you to manage broadly defined trips. Whether it's a taxi driver, food/parcel delivery, outdoor run, or anyone who needs to move from location A to B, Roam.ai location technology helps manage the process.
Trips use a combination of REST APIs and SDK Methods for the creation and management of trips. Trips can be tracked in real-time using our SDK listener methods, webhooks, and our tracking portal track.roam.ai.
Quick Trips lets you track journeys from point A to B in real-time using the startTrip
and endTrip
SDK methods.
Quick Trips are ideal for:
Fitness Tracking while on a run/ride.
Mileage tracking for employees, riders, etc.
Distance tracking for automobile rentals.
Micro mobility apps for short distance tracking.
Quick Trips Workflow
Planned trips lets you plan trips ahead of time where a user can visit a single location or stop at multiple locations as part of the journey from point A to B to C to N. Start by creating a trip using createTrip
including stop_locations
where you can specify this location using coordinates of locations.
The best use cases for planned trips are:
Ridesharing and hailing
Food and Grocery delivery
Last-mile delivery
Logistics
Planned Trips Workflow
Trips require you to use a combination of SDK Methods and APIs to achieve real-time tracking features.
Interaction with the Trip SDK Methods may require you to use user_id
or trip_id
while calling the methods.
Roam.createTrip
Allows you to create a Planned trip with stop_locations
Roam.updateTrip
Allows you to update a trip with user_id
, stop_locations
and more.
Roam.startTrip
Allows you to start a "Quick Trip" or a "Planned Trip" with pre-defined stop_locations
.
Roam.endTrip
Allows you to end a Trip.
Roam.pauseTrip
Allows you to pause a Trip.
Roam.ResumeTrip
Allows you to resume a Trip.
Roam.syncTrip
Allows you to sync an offline Trip.
Roam.getTrip
Allows you to get the trip details using the trip_id
.
Roam.getActiveTrips
Allows you to get a list of active trips for a specific user_id
.
Roam.getTripSummary
Allows you to get a trip summary which includes the trip route, time taken, distance covered, and more.
Roam.subscribeTripStatus
Allows you to subscribe to the real-time status of any ongoing trip.
Roam.deleteTrip
Allows you delete any trip.
The Roam API is organized around REST. Our API has predictable resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.
https://api.roam.ai/v2/trips
Authentication
The Roam API uses API keys to authenticate requests. You can view and manage your API keys in the Roam Dashboard.
Your API keys carry many privileges, so be sure to keep them secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth. Authentication to the API is performed via a custom header Api-Key
. Provide your API key as the value for the header Api-Key
All API requests must be made over HTTPS. Calls made over plain HTTP and API requests without authentication will fail.
Create Trip
Allows you to create a Planned trip with or without origins and destinations.
Get Trip
Allows you to get the trip details using the trip_id
.
Get Multiple Trips
Allows you to get multiple trips.
Update Trip
Allows you to update a trip with user_id
, stop_locations
and more.
Control Trips
Allows you to control a trip like start, end, pause and resume.
Trip Summary
Allows you to get a trip summary which includes the trip route, time taken, distance covered, and more.
Export Trip
Allows you to get a trip summary which includes the trip route, time taken, distance covered, and more.
Delete Trip
Allows you to delete any trip
Trip Object
id
Unique identification of the trip object.
name
Name of the trip.
description
The trip's description.
metadata
A set of key-value pairs that you can attach to the trip object.
trip_state
The current state of the trip.
States: Created
, Started
, or Ended
.
total_distance
Total distance covered by the user for this trip.
total_duration
Total duration taken by the user for this trip
toal_elevation_gain
Total positive elevation gain covered by the user for this trip.
started_at
Timestamp of when the trip started.
ended_at
Timestamp of when the trip ended.
created_at
Timestamp of when the trip was created.
updated_at
Timestamp of when the trip was last updated.
user
List of user objects.
events
List of event objects.
stops
List of stop objects.
User Object
id
Unique identification of the user object.
name
User name
description
User Description
metadata
A set of key-value pairs that you can attach to the user object.
Event Object
id
Unique identifier of the event Object
trip_id
ID associated with the trip.
user_id
User associated with the event.
event_type
Type of trip event: created, started, or ended.
created_at
Timestamp of when the event was created.
event_source
The source of this event, for example: "Trip"
event_version
Version of the event.
Stop Object
id
Unique identifier for the Stop Object
name
The name of the stop.
description
Stop description.
metadata
A Set of key-value pairs that you can attach to the user object.
geometry_radius
The geofence radius of the stop.
geometry
The coordinates of the stop geofence in geoJSON format.
arrived_at
Timestamp of when the user arrived/entered the stop.
departed_at
Timestamp of when the user departed/exited the stop.
created_at
Timestamp of when the stop was created.
updated_at
Timestamp of when the stop was updated.
The end-user can initiate different actions depending on the requirement. This is facilitated by the Roam SDK.
For example, when the end-user clicks on the Start Tracking icon on the frontend, the client-side requests to start tracking the user's location.
To use our Roam SDK on the server-side, the SDK object is instantiated using a private API key. The client request is made using the API which connects to the web server and retrieves the necessary data.
As the name suggests, a Quick Trip creates and starts the trip immediately. The user need not define the locations of travel and can track their journey from point A to point B using the startTrip
and endTrip
SDK methods on their application.
Refer to the following sections to instantiate the Start Quick Trip method on iOS and Android.
Update Trip allows you to update the name, description and the stop locations for a trip.
Consider a scenario where a trip is created with stop locations A, B, and C. If you wish to update the trip with a new stop location D, all the previously created stops need to be passed along with the co ordinates for point D.
If you wish to delete a stop location, you can do so by omitting the co ordinates for that point while updating the trip. However, you can only do so as long as the user has not reached that stop location.
Refer to the following sections for the Update Trip API and SDK methods.
The Create Trip API, specifically used for planned trips, allows you to create new trips with start and stop locations. You can define the geometry radius for these locations which will help capture the entry and exit events.
To instantiate the Create Trip SDK, refer to the following section.
The following section consists of a sample request along with the responses for the Create Trip API.
Once the trip is created, the users can perform various actions to control it. The following sections consist of information on how to integrate the SDKs on iOS and Android devices and the APIs.
The Start Trip method allows you to start a Quick Trip or a planned trip with pre-defined stop locations.
To instantiate the Start Trip SDK method on Android and iOS, refer to the following sections.
The Start Trip API starts the trip for the specified Trip ID.
The End Trip method is used to end an ongoing trip. The ended trip could be previously started, paused, and/or resumed.
Refer to the following section for information on how to instantiate the End Trip SDK on Android and iOS.
The End Trip API is used to end the trip for the given ID.
The Pause Trip method allows the user to pause a previously created trip.
To instantiate the Pause Trip SDK on Android and iOS, refer to the following sections:
Pause Trip API pauses the trip for the given ID.
The Resume Trip method is used to resume a previously paused trip.
The following section gives information on the Resume Trip SDK method for Android and iOS.
Resume trip API resumes the trip for the given Trip ID.
The Sync Trip method syncs an offline trip (with locally stored data) to the servers.
The section below shows the code to instantiate the Sync Trip method on Android and iOS.
The Get Trips API fetches the trip details for the given Trip ID. The information will include the Trip ID, name, description, state, stop locations, entry and exit timestamps at the stop locations and so on.
As the name suggests, Get Single Trip is used to fetch details for a single Trip ID. Refer to the following sections to instantiate the Get Single Trip SDK method on iOS and Android.
Get Single Trip API fetches the trip details for the provided Trip ID.
Get Multiple Trips API will fetch multiple trip details. You can use different parameters to filter out the data to be fetched. For detailed information, refer to the section below.
A trip is active when it is started and not yet ended. The Get Active Trips method returns all the trips that have been started by the user.
Below are the Get Active Trips methods for Android and iOS.
This method helps get the Trip Summary for the specified trip ID. To instantiate the Get Trip Summary method, refer the following section.
The Get Trip Summary API gives information about the entire trip with the start locations, end location stops, events, routes taken, etc.
Refer to the following section for detailed information about the API.
The Subscribe Trip method helps get real-time location data for trips. This method provides location data for both online and offline trips.
For more information on the Subscribe Trip method, refer to the following section.
To subscribe to trip events about end users, you configure Webhooks for your applications. A Webhook registers the notification URL that Roam sends notifications to.
To use the Developer Dashboard to subscribe to event notifications, refer to the following section.
There are several backend libraries you can subscribe to to receive user trips event data. We provide three libraries for location and events subscription.
For detailed information on how to integrate our JavaScript, Go and Python libraries, refer to the following sections.
The Export trip API call consolidates the trip summary in a readable format and exports the data to your system.
The different formats supported by Roam are csv, gpx, json and geojson. Refer to the following section for the API.
The Delete Trip method deletes the trip regardless of its state.
To instantiate the Delete Trip method on Android and iOS, refer the following section.
The Delete Trip API makes a soft delete of the trip for the given trip ID.
The following are some of the commonly found codes indicating client errors.
400
invalid_request_error
The request was unacceptable due to a missing parameter or an invalid parameter.
401
invalid_api_key
No valid API key provided or API key is missing.
402
account_error
The parameters were valid but the request failed due to either a payment error or the organization disabled it or you have exceeded your usage.
404
object_not_found
The requested object does not exist or has already been deleted.
429
rate_limit_exceeded
Too many requests hit the API too quickly. We recommend an exponential backoff of your requests.
Now that you know how to instantiate our SDK methods and how the APIs function, you can create, start and control the trips using the same. You can publish location updates and also subscribe to the trip using our Roam SDK. To receive real-time location updates, we have made a provision to subscribe to Webhooks and Backend libraries. However, you can also track the trip using our Roam Tracking Dashboard.
The Roam Tracking dashboard is a fully responsive, platform compatible, and an easy-to-use interface that helps track the end-user location during a trip.
You can either provide the UserID or the TripID to start tracking. You can also create a new user with an existing API Key.
The Tracking dashboard shows the following:
The number of stops in the created trip.
The total distance traveled from the start to the end location.
The duration taken to travel the distance.
The arrival and departure timestamps for the entry and exit events at each stop location.
ID of the end-user who traversed the distance.
In the above example, we have created a trip with three stop locations. Once the trip is created and started, the stop locations are visible on the tracking dashboard in yellow.
Check out the video below for a short demo of the tracking dashboard.
Once the trip is ended, you can see the start point indicated in green, stop locations in yellow, and the endpoint in red.
Explore Roam's Geofencing documentation.
Geofence is a virtual perimeter for a real-world geographical area. A geofence can be dynamically generated around a location point with a radius (circle geofence) or with a pre-defined set of boundaries (polygon geofence) for stores, neighborhoods, or even cities.
Every time the end user enters or exits a geofence with a location aware device, events are generated. These events can be used to alert the user or perform actions in the backend.
The Roam API is organized around REST. Our API has predictable resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.
https://api.roam.ai/v1/api/geofence
Roam API uses API keys to authenticate requests. You can view and manage your API keys in the Roam Dashboard.
Your API keys carry many privileges, so be sure to keep them secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth. Authentication to the API is performed via a custom header Api-Key
. Provide your API key as the value for the header Api-Key
Geofences can be created using the Roam API. They can be created over a circle or a polygon geometry. By default, a geofence is applicable to all the users of a project but can also be restricted to a group of users. Geofences can be configured to be enabled for a specified time interval.
Roam allows you to create two geofence geometry types:
Circle
Polygon
A circular geofence is the region around a location point defined by a radius. To create a circular geofence, the required body parameters are coordinates
, and geometry_radius
.
Sample Request // Circle Geofence
curl --location --request POST 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '{
"coordinates": [ -72.28122, 42.926042 ] ,
"geometry_radius": 177,
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"]
}'
Sample Response // Circle Geofence
{
"status": true,
"msg": "Geofence Added successfully.",
"code": 201,
"data": {
"geofence_id": "60e59c73ffb3fb58a9c6eb64",
"geometry_type": "circle",
"geometry_radius": 177,
"geometry_center": {
"type": "Point",
"coordinates": [
-72.28122,
42.926042
]
},
"is_enabled": [
true,
"2021-06-10T18:45:00.000",
"2021-06-10T19:29:00.000"
],
"is_deleted": false,
"created_at": "2021-07-07T12:22:11.105",
"updated_at": "2021-07-07T12:22:11.105"
}
}
A polygon geofence is the area defined by a set of boundaries forming any shape around a location area. To create a polygon geofence, the required body parameters are geometry_type
andcoordinates
.
Same Request to create a Polygon geofence
curl --location --request POST 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '
{
"coordinates":[
[
-0.08789347686767579,
51.50619618452938
],
[
-0.0905934768676758,
51.50619618452938
],
[
-0.0905934768676758,
51.503796184529385
],
[
-0.08789347686767579,
51.50619618452938
]
],
"is_enabled": [
true,
"2021-06-10T18:45:00",
"2021-06-10T19:29:00"
]
}'
Sample Response
{
"status": true,
"msg": "Geofence Added successfully.",
"code": 201,
"data": {
"geofence_id": "60e59cfaffb3fb58a8c6eb66",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-0.08789347686767579,
51.50619618452938
],
[
-0.0905934768676758,
51.50619618452938
],
[
-0.0905934768676758,
51.503796184529385
],
[
-0.08789347686767579,
51.50619618452938
]
]
]
},
"geometry_type": "polygon",
"geometry_center": {
"type": "Point",
"coordinates": [
-0.08969347686882724,
51.505396185373506
]
},
"is_enabled": [
true,
"2021-06-10T18:45:00.000",
"2021-06-10T19:29:00.000"
],
"is_deleted": false,
"created_at": "2021-07-07T12:24:26.197",
"updated_at": "2021-07-07T12:24:26.197"
}
}
You can monitor geofence events for a specific user or a list of users by passing user_ids
which are generated at the time of creating a user. In the case of a user group, you may pass the group_id. If by default, user_ids
and group_ids
are not specified, then the geofence is activated for all the users of the project.
Pass a user_id
under the "user_ids"
body parameter. Pass an array ofuser_ids
to create a geofence specific to multiple users.
Sample Request for single User ID
curl --location --request POST 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '{
"geometry_type": "circle",
"coordinates": [ -72.28122, 42.926042 ] ,
"geometry_radius": 177,
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"],
"user_ids": ["6bda16edea01848b3b419163"]
}'
Sample Request for multiple User IDs
curl --location --request POST 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '{
"geometry_type": "circle",
"coordinates": [ -72.28122, 42.926042 ] ,
"geometry_radius": 177,
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"],
"user_ids": ["6bda16edea01848b3b419163", "6bda16edea01848b3b419163"]
}'
Pass a group_id
under the "group_ids"
body parameter. You may pass multiple group IDs into an array to create a geofence specific to those groups.
Sample Request for single Group ID
curl --location --request POST 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '{
"geometry_type": "circle",
"coordinates": [ -72.28122, 42.926042 ] ,
"geometry_radius": 177,
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"],
"group_ids": ["6bda16edea01848b3b419163"]
}'
Sample Request for multiple Group ID
curl --location --request POST 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '{
"geometry_type": "circle",
"coordinates": [ -72.28122, 42.926042 ] ,
"geometry_radius": 177,
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"],
"group_ids": ["6bda16edea01848b3b419163", "6bda16edea01848b3b419163"]
}'
You can create time aware geofences to trigger events between a specific time range. You can do so by passing the date and time as the second and third elements of the array to theis_enabled
field in the body section.
During the specified time interval, the entry and exit events will be triggered. However, outside the time interval, you need to ensure that the"is_enabled"
field is set to "false".
curl --location --request POST 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '{
"geometry_type": "circle",
"coordinates": [ -72.28122, 42.926042 ] ,
"geometry_radius": 177,
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"]
}'
Sample Response
{
"status": true,
"msg": "Geofence Added successfully.",
"code": 201,
"data": {
"geofence_id": "60e59e9effb3fb58a3c6eb69",
"geometry_type": "circle",
"geometry_radius": 177,
"geometry_center": {
"type": "Point",
"coordinates": [
-72.28122,
42.926042
]
},
"is_enabled": [
true,
"2021-06-10T18:45:00.000",
"2021-06-10T19:29:00.000"
],
"is_deleted": false,
"created_at": "2021-07-07T12:31:26.437",
"updated_at": "2021-07-07T12:31:26.437"
}
}
Adding a description
and metadata
can help identify and personalize the geofences while displaying them on a map. You can add this information while creating a geofence or updating a geofence.
Sample Request
curl --location --request POST 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '{
"geometry_type": "circle",
"coordinates": [ -72.28122, 42.926042 ] ,
"geometry_radius": 177,
"description": "Google New York City",
"metadata": {
"object_id": "10000234243241234",
"google_user_id": "000034"
},
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"]
}'
Sample Response
{
"status": true,
"msg": "Geofence Added successfully.",
"code": 201,
"data": {
"geofence_id": "60ee5decffb3fb728a120cb4",
"geometry_type": "circle",
"geometry_radius": 177,
"geometry_center": {
"type": "Point",
"coordinates": [
-72.28122,
42.926042
]
},
"is_enabled": [
true,
"2021-06-10T18:45:00.000",
"2021-06-10T19:29:00.000"
],
"description": "Google New York City",
"metadata": {
"object_id": "10000234243241234",
"google_user_id": "000034"
},
"is_deleted": false,
"created_at": "2021-07-14T03:45:48.842",
"updated_at": "2021-07-14T03:45:48.842"
}
}
Adding tag
can help filter geofences easily. This field is optional. When a geofence event is generated, the tag
is also sent along with the event.
color_code
defines the color of the geofence and how it is displayed on the dashboard. Hex Code for CSS colors should be passed in this field without '#
'.
Sample Request
curl --location --request POST 'https://api.roam.ai/v1/api/geofence/' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88' \
--header 'Content-Type: application/json' \
--data-raw '{
"coordinates": [ -72.28122, 42.926042 ] ,
"geometry_radius": 177,
"description": "Google New York City",
"metadata": {
"object_id": "10000234243241234",
"google_user_id": "000034"
},
"tag": "home",
"color_code": "ffffff",
"is_enabled": [true, "2021-06-10T18:45:00", "2021-06-10T19:29:00"]
}'
Sample Response
{
"status": true,
"msg": "Geofence Added successfully.",
"code": 201,
"data": {
"geofence_id": "60ee5e1effb3fb728c120d88",
"geometry_type": "circle",
"geometry_radius": 177,
"geometry_center": {
"type": "Point",
"coordinates": [
-72.28122,
42.926042
]
},
"is_enabled": [
true,
"2021-06-10T18:45:00.000",
"2021-06-10T19:29:00.000"
],
"description": "Google New York City",
"color_code": "ffffff",
"tag": "home",
"metadata": {
"object_id": "10000234243241234",
"google_user_id": "000034"
},
"is_deleted": false,
"created_at": "2021-07-14T03:46:38.674",
"updated_at": "2021-07-14T03:46:38.674"
}
}
Geofence can be updated using PUT
API request along with the geofence endpoint.
The following are the values that can be updated once after the Geofence is created.
Parameters
Type
group_ids
array
user_ids
array
metadata
object
color_code
string
tag
string
description
string
is_enabled
array
The values that cannot be updated once the geofence is created are:
Parameters
Type
coordinates
array
geometry_type
string
geometry_radius
integer
This API gives you a filtered list of geofences. You can filter by geofence_id
, created_at, start_date
and end_date
fields, user_id
and group_id.
Sample Request
This filter allows you to filter the geofences within the given date range. These are non-mandatory fields and will be set to the current date by default.
You may also pass either the start_date
or the end_date
as filters. If you pass a specific start date, make sure it is less than the current date since the end date will be set default to the current date. If you pass a specific end_date
and leave the start_date
empty, make sure it is greater than the current date.
Below are the acceptable formats for the date filter:
Parameter
Mandatory
Format
Default
start_date
No
YYYY-MM-DD
Current date
end_date
No
YYYY-MM-DD
Current date
curl --location --request GET 'https://api.roam.ai/v1/api/geofence/?start_date=2020-09-28&end_date=2020-09-29' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88'
You can also use geofence_id
as a filter. If you pass a valid geofence_id
, the results will be filtered to the given geofence id.
You can get the geofence_id
when you create a geofence using the Create Geofence API.
Make sure the geofence_id
used here belongs to the same project linked to the API key.
curl --location --request GET 'https://api.roam.ai/v1/api/geofence/?geofence_id=5f73326ce5fc231ba4b253eb' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88'
Similar to the geofence_id
, you can fetch the list of geofences that are tagged with the given user_id
, which was initially used during the Create Geofence API. The user_id
is created within the SDK during thecreateUser
method and returns a unique user_id
for identification within the Roam environment.
If you use theuser_id
as a filter along with the date filter, the date filters will not be considered. And if you pass an empty or invalid user_id
, the API will return an error.
Make sure the user_id
used here belongs to the same project linked with the API key.
curl --location --request GET 'https://api.roam.ai/v1/api/geofence/?user_id=6073325bcf3e4eba5a1123a' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88'
To fetch the list of geofences that are tagged with the given group_id
, which was initially used during the Create Geofence API, you can pass the group_id
in the header parameter.
You can get the group_id
when you create a group using the Create Group API.
If you use group_id
as a filter along with the date filter, the date filters will not be considered. Passing an empty or invalid group_id
, will return an error.
Make sure the group_id
used here belongs to the same project linked with the API key.
curl --location --request GET 'https://api.roam.ai/v1/api/geofence/?group_id=6073325bc3fe343ab6c1324b' \
--header 'Api-Key: e566c098cc6b441a9c3453b6fcf76e88'
Roam's geofence feature has 2 possible events that can be triggered based on user behavior:
Geofence Entry Event - triggered when a user enters the defined geofence area
Geofence Exit Event - triggered when a user exits from the defined geofence area
Sample Events:
Geofence Entry Event:
{
"events": [
{
"user_id": "60e5646151efb06fe4c65b0d",
"location_id": "60e566a4fa8a780000ed3194",
"geofence_id": "60e566a28ce7db5726c1c1cd",
"recorded_at": "2021-07-07T08:32:36.243Z",
"event_source": "geospark:geofence",
"event_version": "1.0",
"event_type": "geospark:geofence:entry",
"location": {
"type": "Point",
"coordinates": [
77.5573154,
9.4551286
]
},
"speed": 0,
"course": 316.1922912597656,
"altitude": 78.46394327410016,
"activity": "M",
"vertical_accuracy": null,
"horizontal_accuracy": 10.565999984741211
}
]
}
Geofence Exit Event:
{
"events": [
{
"user_id": "60e5646151efb06fe4c65b0d",
"location_id": "60e566a4fa8a780000ed3194",
"geofence_id": "60e566a28ce7db5726c1c1cd",
"recorded_at": "2021-07-07T08:32:36.243Z",
"event_source": "geospark:geofence",
"event_version": "1.0",
"event_type": "geospark:geofence:exit",
"location": {
"type": "Point",
"coordinates": [
77.5573154,
9.4551286
]
},
"speed": 0,
"course": 316.1922912597656,
"altitude": 78.46394327410016,
"activity": "M",
"vertical_accuracy": 5,
"horizontal_accuracy": 10.565999984741211
}
]
}
To enable geofence events for a user, you’ll need to ensure the following:
Under Roam.toggleEvents
the geofence
flag must be set to true
,and
Ensure you’re publishing location to the server.
Toggle Events docs Links: iOS | Android | React Native | Using API
Publish Locations docs links: iOS | Android | React Native
If the geofence flag is false for a user and location is not being published, then geofence events will not be processed for their location updates.
Roam supports the posting of events to webhooks in real-time. To enable posting events via webhook, first the webhook URL needs to be configured in the project using the dashboard (Project Settings -> integration) and should be enabled.
Geofence events can be retrieved using the Roam API. The Get Events API lets you fetch entry or exit events of the users from your event-enabled geofences. The API also lets you filter by user, geofence, location, and more.
Delete any existing geofences from your projects by using the geofence_id.
You can delete the geofence with the delete API using the following two options:
Option 1: Delete geofence individually
You can delete one geofence at a time by passing the geofence ID as a query parameter.
Option 2: Delete geofences in bulk
By passing multiple geofence_ids as a body parameter, you can delete up to 200 geofences at a time.
Method
Status
Message
Reason
GET
400
"Error": [ "start_date provided is greater than end_date." ]
Invalid date filter
GET
400
"geofence_id": { "geofence_id": "This field is invalid." }
Invalid geofence id
GET
400
"Error": [ "Geofence does not exist." ]
Geofence does not exist
GET
400
"Error": [ "You are not authorized." ]
Invalid API key
GET
400
"Error": [ "Maximum 7 days data is allowed at a time." ]
Date filter greater than the limit of 7 days
GET
400
"ErrorMessage": "An error occurred"
Unknown server error
POST
400
"coordinates": [ "Invalid coordinates for given geometry type" ]
Invalid geofence geometry coordinates
POST
400
"enable_at": [ "DateTime has wrong format. Provide as YYYY-MM-DDThh:mm:ss" ]
Invalid date time format
POST
400
"non_field_errors": [ "enable_at provided is greater than disable_at." ]
Invalid enable_at value
POST
400
"non_field_errors": [ "disable_at field is required when enable_at field is present." ]
Empty disable_at value
POST
400
"non_field_errors": [ "enable_at field is required when disable_at field is present." ]
Empty enable_at value
POST
400
"Invalid is_enabled format. Allowed format: [bool, enable_at, disable_at]"
Invalid is_enabled format
POST
400
"coordinates": [ "Coordinates must be sent in a list" ]
Invalid coordinates
POST
400
"geometry_radius": [ "This field is required." ]
Empty geometry radius
POST
400
"tag": { "tag": "This field is invalid." }
Invalid tag
PUT
400
"geofence_id": { "geofence_id": "This field is invalid." }
Invalid geofence id
DELETE
400
"details": "This geofence is part of an active campaign."
Geofence cannot be deleted since it is part of an active campaign
DELETE
400
"geofence_id": { "geofence_id": "This field is invalid." }
Invalid geofence id
Explore how to get a trip summary with our Trip API
GET
https://api.roam.ai/v2/trips/:id/summary
Get the summary of the given trip id.
id*
String
Retrieves the trip summary with the given ID.
Authorization*
String
Bearer <API-KEY>
{
"code": 200,
"description": "The trip summary for requested id.",
"message": "trip_summary",
"trip": {
"id": "6221bf4393ade81ce90c8c5c",
"trip_state": "ended",
"total_distance": 1942.08,
"total_duration": 328,
"total_elevation_gain": 52,
"name": "trip name",
"description": "trip description",
"metadata": {
"Key1": "value1"
},
"start_location": {
"id": "6221bf683d4d460000e33446",
"metadata": {},
"address": "Bailey Road, Priyadarshi Nagar, Danapur, Dinapur-Cum-Khagaul, Patna District, Bihar, 801506, India",
"recorded_at": "2022-03-04T07:27:36.645",
"geometry": {
"type": "Point",
"coordinates": [
85.06961939,
25.60647234
]
}
},
"end_location": {
"id": "6221c1493d4d460000e334c1",
"metadata": {},
"address": "Priyadarshi Nagar, Danapur, Dinapur-Cum-Khagaul, Patna District, Bihar, 800018, India",
"recorded_at": "2022-03-04T07:35:37.382",
"geometry": {
"type": "Point",
"coordinates": [
85.06689824,
25.61904625
]
}
},
"started_at": "2022-03-04T07:27:36.645",
"ended_at": "2022-03-04T07:35:37.382",
"created_at": "2022-03-04T07:26:59.480",
"updated_at": "2022-03-04T07:35:39.913",
"user": {
"id": "6221bc24ffb3fb125a2e2342",
"name": "",
"description": "",
"metadata": {
"Mobile": "1234567890",
"Name": "Nikhil"
}
},
"stops": [
{
"id": "6221bf4393ade81ce90c8c5b",
"name": "STOP 1",
"description": "tea break",
"metadata": {
"Key1": "value1"
},
"address": "Bangalore",
"geometry_radius": 600,
"geometry": {
"type": "Point",
"coordinates": [
85.30614739,
23.5155215
]
},
"created_at": "2022-03-04T07:26:59.475",
"updated_at": "2022-03-04T07:26:59.475",
"arrived_at": null,
"departed_at": null
}
],
"events": [
{
"id": "6221bf45b5ef8c40ac13ff5e",
"trip_id": "6221bf4393ade81ce90c8c5c",
"location_id": "",
"user_id": "6221bc24ffb3fb125a2e2342",
"event_type": "roam:trip:created",
"created_at": "2022-03-04T07:27:01.615",
"event_source": "roam:trip",
"event_version": "1.0"
},
{
"id": "6221bf6e1674e3543f398a40",
"trip_id": "6221bf4393ade81ce90c8c5c",
"location_id": "6221bf683d4d460000e33446",
"user_id": "6221bc24ffb3fb125a2e2342",
"event_type": "roam:trip:started",
"created_at": "2022-03-04T07:27:41.257",
"event_source": "roam:trip",
"event_version": "1.0"
},
{
"id": "6221c0701674e3543f398a41",
"trip_id": "6221bf4393ade81ce90c8c5c",
"location_id": "6221c06d3d4d460000e3346c",
"user_id": "6221bc24ffb3fb125a2e2342",
"event_type": "roam:trip:paused",
"created_at": "2022-03-04T07:31:59.919",
"event_source": "roam:trip",
"event_version": "1.0"
},
{
"id": "6221c0e1b5ef8c40ac13ff5f",
"trip_id": "6221bf4393ade81ce90c8c5c",
"location_id": "6221c0dd3d4d460000e33492",
"user_id": "6221bc24ffb3fb125a2e2342",
"event_type": "roam:trip:resumed",
"created_at": "2022-03-04T07:33:53.222",
"event_source": "roam:trip",
"event_version": "1.0"
},
{
"id": "6221c14d1674e3543f398a42",
"trip_id": "6221bf4393ade81ce90c8c5c",
"location_id": "6221c1493d4d460000e334c1",
"user_id": "6221bc24ffb3fb125a2e2342",
"event_type": "roam:trip:ended",
"created_at": "2022-03-04T07:35:41.291",
"event_source": "roam:trip",
"event_version": "1.0"
}
],
"route_indexes": [
[
1,
39
],
[
40,
86
]
],
"route": [
{
"coordinates": {
"coordinates": [
85.06961939,
25.60647234
],
"type": "Point"
},
"speed": 0,
"altitude": 110,
"activity": "STOP",
"recorded_at": "2022-03-04T07:27:36.645",
"metadata": null,
"distance": 0,
"duration": 0,
"elevation_gain": 0
},
{
"coordinates": {
"coordinates": [
85.06968719,
25.60665091
],
"type": "Point"
},
"speed": 13,
"altitude": 129.82,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:28:31.744",
"metadata": null,
"distance": 21.01,
"duration": 55,
"elevation_gain": 19
},
{
"coordinates": {
"coordinates": [
85.06948914,
25.60671479
],
"type": "Point"
},
"speed": 6,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:28:41.816",
"metadata": null,
"distance": 42.12,
"duration": 65,
"elevation_gain": 20
},
{
"coordinates": {
"coordinates": [
85.06929126,
25.60677863
],
"type": "Point"
},
"speed": 14,
"altitude": 129.38,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:29:04.882",
"metadata": null,
"distance": 63.21,
"duration": 88,
"elevation_gain": 20
},
{
"coordinates": {
"coordinates": [
85.06904013,
25.60685963
],
"type": "Point"
},
"speed": 24,
"altitude": 129.91,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:29:09.838",
"metadata": null,
"distance": 89.98,
"duration": 92,
"elevation_gain": 20
},
{
"coordinates": {
"coordinates": [
85.06883539,
25.60692568
],
"type": "Point"
},
"speed": 7,
"altitude": 129.44,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:29:16.823",
"metadata": null,
"distance": 111.8,
"duration": 98,
"elevation_gain": 20
},
{
"coordinates": {
"coordinates": [
85.06863859,
25.60698916
],
"type": "Point"
},
"speed": 12,
"altitude": 129.26,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:29:30.928",
"metadata": null,
"distance": 132.78,
"duration": 112,
"elevation_gain": 20
},
{
"coordinates": {
"coordinates": [
85.0684211,
25.60706062
],
"type": "Point"
},
"speed": 22,
"altitude": 128.27,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:29:35.939",
"metadata": null,
"distance": 156.01,
"duration": 117,
"elevation_gain": 20
},
{
"coordinates": {
"coordinates": [
85.06820577,
25.60713976
],
"type": "Point"
},
"speed": 16,
"altitude": 127.77,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:29:41.011",
"metadata": null,
"distance": 179.35,
"duration": 122,
"elevation_gain": 20
},
{
"coordinates": {
"coordinates": [
85.06800858,
25.60721223
],
"type": "Point"
},
"speed": 11,
"altitude": 127.61,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:29:45.849",
"metadata": null,
"distance": 200.72,
"duration": 126,
"elevation_gain": 20
},
{
"coordinates": {
"coordinates": [
85.06781342,
25.60728395
],
"type": "Point"
},
"speed": 9,
"altitude": 128.85,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:10.860",
"metadata": null,
"distance": 221.87,
"duration": 151,
"elevation_gain": 21
},
{
"coordinates": {
"coordinates": [
85.06759802,
25.60736312
],
"type": "Point"
},
"speed": 18,
"altitude": 128.68,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:15.998",
"metadata": null,
"distance": 245.21,
"duration": 156,
"elevation_gain": 21
},
{
"coordinates": {
"coordinates": [
85.06739371,
25.60743821
],
"type": "Point"
},
"speed": 11,
"altitude": 129.95,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:21.892",
"metadata": null,
"distance": 267.35,
"duration": 161,
"elevation_gain": 23
},
{
"coordinates": {
"coordinates": [
85.0672014,
25.60751067
],
"type": "Point"
},
"speed": 12,
"altitude": 128.69,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:26.826",
"metadata": null,
"distance": 288.27,
"duration": 165,
"elevation_gain": 23
},
{
"coordinates": {
"coordinates": [
85.06700945,
25.60758558
],
"type": "Point"
},
"speed": 16,
"altitude": 128.34,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:32.845",
"metadata": null,
"distance": 309.26,
"duration": 171,
"elevation_gain": 23
},
{
"coordinates": {
"coordinates": [
85.06679251,
25.60767003
],
"type": "Point"
},
"speed": 17,
"altitude": 128.24,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:38.918",
"metadata": null,
"distance": 332.97,
"duration": 177,
"elevation_gain": 23
},
{
"coordinates": {
"coordinates": [
85.06660112,
25.60774419
],
"type": "Point"
},
"speed": 13,
"altitude": 128.32,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:42.852",
"metadata": null,
"distance": 353.88,
"duration": 180,
"elevation_gain": 23
},
{
"coordinates": {
"coordinates": [
85.06638153,
25.60782928
],
"type": "Point"
},
"speed": 19,
"altitude": 127.84,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:47.844",
"metadata": null,
"distance": 377.87,
"duration": 184,
"elevation_gain": 23
},
{
"coordinates": {
"coordinates": [
85.0661767,
25.60790865
],
"type": "Point"
},
"speed": 26,
"altitude": 128.25,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:52.856",
"metadata": null,
"distance": 400.24,
"duration": 189,
"elevation_gain": 23
},
{
"coordinates": {
"coordinates": [
85.06594634,
25.60799497
],
"type": "Point"
},
"speed": 31,
"altitude": 128.76,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:55.981",
"metadata": null,
"distance": 425.28,
"duration": 192,
"elevation_gain": 24
},
{
"coordinates": {
"coordinates": [
85.06573304,
25.60807386
],
"type": "Point"
},
"speed": 31,
"altitude": 127.26,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:30:58.857",
"metadata": null,
"distance": 448.42,
"duration": 194,
"elevation_gain": 24
},
{
"coordinates": {
"coordinates": [
85.06547511,
25.60817058
],
"type": "Point"
},
"speed": 34,
"altitude": 128.9,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:01.830",
"metadata": null,
"distance": 476.46,
"duration": 196,
"elevation_gain": 25
},
{
"coordinates": {
"coordinates": [
85.06521008,
25.60824988
],
"type": "Point"
},
"speed": 31,
"altitude": 129.79,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:04.882",
"metadata": null,
"distance": 504.49,
"duration": 199,
"elevation_gain": 26
},
{
"coordinates": {
"coordinates": [
85.0649913,
25.6083136
],
"type": "Point"
},
"speed": 25,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:07.885",
"metadata": null,
"distance": 527.56,
"duration": 202,
"elevation_gain": 26
},
{
"coordinates": {
"coordinates": [
85.06477762,
25.60837584
],
"type": "Point"
},
"speed": 29,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:11.031",
"metadata": null,
"distance": 550.1,
"duration": 205,
"elevation_gain": 26
},
{
"coordinates": {
"coordinates": [
85.06452776,
25.60844861
],
"type": "Point"
},
"speed": 32,
"altitude": 129.09,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:13.865",
"metadata": null,
"distance": 576.45,
"duration": 207,
"elevation_gain": 26
},
{
"coordinates": {
"coordinates": [
85.06426739,
25.60851561
],
"type": "Point"
},
"speed": 31,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:16.873",
"metadata": null,
"distance": 603.63,
"duration": 210,
"elevation_gain": 27
},
{
"coordinates": {
"coordinates": [
85.06405443,
25.60857429
],
"type": "Point"
},
"speed": 24,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:19.974",
"metadata": null,
"distance": 625.98,
"duration": 213,
"elevation_gain": 27
},
{
"coordinates": {
"coordinates": [
85.06386509,
25.60864441
],
"type": "Point"
},
"speed": 24,
"altitude": 129.01,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:22.914",
"metadata": null,
"distance": 646.52,
"duration": 215,
"elevation_gain": 27
},
{
"coordinates": {
"coordinates": [
85.06364274,
25.60872913
],
"type": "Point"
},
"speed": 31,
"altitude": 128.36,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:26.044",
"metadata": null,
"distance": 670.75,
"duration": 218,
"elevation_gain": 27
},
{
"coordinates": {
"coordinates": [
85.06341159,
25.60881739
],
"type": "Point"
},
"speed": 20,
"altitude": 129.18,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:29.963",
"metadata": null,
"distance": 695.94,
"duration": 221,
"elevation_gain": 28
},
{
"coordinates": {
"coordinates": [
85.06322453,
25.60888629
],
"type": "Point"
},
"speed": 23,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:33.856",
"metadata": null,
"distance": 716.22,
"duration": 224,
"elevation_gain": 29
},
{
"coordinates": {
"coordinates": [
85.06302312,
25.60895644
],
"type": "Point"
},
"speed": 19,
"altitude": 129.83,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:38.029",
"metadata": null,
"distance": 737.89,
"duration": 228,
"elevation_gain": 29
},
{
"coordinates": {
"coordinates": [
85.06280411,
25.60903273
],
"type": "Point"
},
"speed": 22,
"altitude": 128.76,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:41.848",
"metadata": null,
"distance": 761.45,
"duration": 231,
"elevation_gain": 29
},
{
"coordinates": {
"coordinates": [
85.06256706,
25.60911529
],
"type": "Point"
},
"speed": 22,
"altitude": 128.39,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:45.793",
"metadata": null,
"distance": 786.95,
"duration": 234,
"elevation_gain": 29
},
{
"coordinates": {
"coordinates": [
85.0623316,
25.6091994
],
"type": "Point"
},
"speed": 31,
"altitude": 129.52,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:48.884",
"metadata": null,
"distance": 812.37,
"duration": 237,
"elevation_gain": 30
},
{
"coordinates": {
"coordinates": [
85.06211789,
25.60929494
],
"type": "Point"
},
"speed": 27,
"altitude": 128.6,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:51.924",
"metadata": null,
"distance": 836.31,
"duration": 240,
"elevation_gain": 30
},
{
"coordinates": {
"coordinates": [
85.06193204,
25.60937814
],
"type": "Point"
},
"speed": 24,
"altitude": 129.52,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:31:54.941",
"metadata": null,
"distance": 857.13,
"duration": 243,
"elevation_gain": 31
},
{
"coordinates": {
"coordinates": [
85.06182,
25.60942829
],
"type": "Point"
},
"speed": 0,
"altitude": 129.91,
"activity": "STOP",
"recorded_at": "2022-03-04T07:31:57.273",
"metadata": null,
"distance": 869.68,
"duration": 245,
"elevation_gain": 31
},
{
"coordinates": {
"coordinates": [
85.06280688,
25.61014692
],
"type": "Point"
},
"speed": 0,
"altitude": 127.47762887,
"activity": "STOP",
"recorded_at": "2022-03-04T07:33:51.349",
"metadata": null,
"distance": 869.68,
"duration": 0,
"elevation_gain": 31
},
{
"coordinates": {
"coordinates": [
85.06297614,
25.61050536
],
"type": "Point"
},
"speed": 39,
"altitude": 129.96,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:33:53.057",
"metadata": null,
"distance": 913.04,
"duration": 246,
"elevation_gain": 34
},
{
"coordinates": {
"coordinates": [
85.06306297,
25.61068923
],
"type": "Point"
},
"speed": 39,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:33:55.087",
"metadata": null,
"distance": 935.28,
"duration": 248,
"elevation_gain": 34
},
{
"coordinates": {
"coordinates": [
85.0631498,
25.6108731
],
"type": "Point"
},
"speed": 39,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:33:56.975",
"metadata": null,
"distance": 957.52,
"duration": 249,
"elevation_gain": 34
},
{
"coordinates": {
"coordinates": [
85.06323663,
25.61105697
],
"type": "Point"
},
"speed": 39,
"altitude": 129.62,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:33:58.909",
"metadata": null,
"distance": 979.76,
"duration": 250,
"elevation_gain": 34
},
{
"coordinates": {
"coordinates": [
85.06331741,
25.61122804
],
"type": "Point"
},
"speed": 34,
"altitude": 129.15,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:01.095",
"metadata": null,
"distance": 1000.45,
"duration": 252,
"elevation_gain": 34
},
{
"coordinates": {
"coordinates": [
85.06339631,
25.61139512
],
"type": "Point"
},
"speed": 38,
"altitude": 127.42,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:02.978",
"metadata": null,
"distance": 1020.66,
"duration": 253,
"elevation_gain": 34
},
{
"coordinates": {
"coordinates": [
85.06348155,
25.61157489
],
"type": "Point"
},
"speed": 39,
"altitude": 125.79,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:04.978",
"metadata": null,
"distance": 1042.42,
"duration": 255,
"elevation_gain": 34
},
{
"coordinates": {
"coordinates": [
85.06356958,
25.6117583
],
"type": "Point"
},
"speed": 39,
"altitude": 126.78,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:07.109",
"metadata": null,
"distance": 1064.66,
"duration": 257,
"elevation_gain": 35
},
{
"coordinates": {
"coordinates": [
85.06365239,
25.61194366
],
"type": "Point"
},
"speed": 39,
"altitude": 127.96,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:09.097",
"metadata": null,
"distance": 1086.9,
"duration": 258,
"elevation_gain": 36
},
{
"coordinates": {
"coordinates": [
85.06372888,
25.61211659
],
"type": "Point"
},
"speed": 34,
"altitude": 128.9,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:11.004",
"metadata": null,
"distance": 1107.62,
"duration": 259,
"elevation_gain": 37
},
{
"coordinates": {
"coordinates": [
85.06380536,
25.61228952
],
"type": "Point"
},
"speed": 39,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:13.006",
"metadata": null,
"distance": 1128.34,
"duration": 261,
"elevation_gain": 38
},
{
"coordinates": {
"coordinates": [
85.06390366,
25.61246859
],
"type": "Point"
},
"speed": 39,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:14.985",
"metadata": null,
"distance": 1150.58,
"duration": 262,
"elevation_gain": 38
},
{
"coordinates": {
"coordinates": [
85.06397223,
25.61264941
],
"type": "Point"
},
"speed": 36,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:16.988",
"metadata": null,
"distance": 1171.85,
"duration": 264,
"elevation_gain": 38
},
{
"coordinates": {
"coordinates": [
85.06403591,
25.61282275
],
"type": "Point"
},
"speed": 36,
"altitude": 128.43,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:18.946",
"metadata": null,
"distance": 1192.17,
"duration": 265,
"elevation_gain": 38
},
{
"coordinates": {
"coordinates": [
85.0641024,
25.6129951
],
"type": "Point"
},
"speed": 36,
"altitude": 127.34,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:21.022",
"metadata": null,
"distance": 1212.48,
"duration": 267,
"elevation_gain": 38
},
{
"coordinates": {
"coordinates": [
85.06418866,
25.61316979
],
"type": "Point"
},
"speed": 39,
"altitude": 127.88,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:22.997",
"metadata": null,
"distance": 1233.76,
"duration": 268,
"elevation_gain": 39
},
{
"coordinates": {
"coordinates": [
85.06430193,
25.61339917
],
"type": "Point"
},
"speed": 30,
"altitude": 128.38,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:26.011",
"metadata": null,
"distance": 1261.71,
"duration": 271,
"elevation_gain": 39
},
{
"coordinates": {
"coordinates": [
85.06441341,
25.61362491
],
"type": "Point"
},
"speed": 38,
"altitude": 129.56,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:29.227",
"metadata": null,
"distance": 1289.21,
"duration": 274,
"elevation_gain": 40
},
{
"coordinates": {
"coordinates": [
85.06452199,
25.6138474
],
"type": "Point"
},
"speed": 29,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:32.071",
"metadata": null,
"distance": 1316.26,
"duration": 276,
"elevation_gain": 41
},
{
"coordinates": {
"coordinates": [
85.06460088,
25.61401364
],
"type": "Point"
},
"speed": 36,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:34.039",
"metadata": null,
"distance": 1336.38,
"duration": 277,
"elevation_gain": 41
},
{
"coordinates": {
"coordinates": [
85.06468287,
25.6141864
],
"type": "Point"
},
"speed": 37,
"altitude": 129.06,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:35.987",
"metadata": null,
"distance": 1357.29,
"duration": 278,
"elevation_gain": 41
},
{
"coordinates": {
"coordinates": [
85.06477006,
25.61437013
],
"type": "Point"
},
"speed": 39,
"altitude": 128.43,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:38.046",
"metadata": null,
"distance": 1379.53,
"duration": 280,
"elevation_gain": 41
},
{
"coordinates": {
"coordinates": [
85.06485726,
25.61455386
],
"type": "Point"
},
"speed": 39,
"altitude": 128.77,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:40.104",
"metadata": null,
"distance": 1401.77,
"duration": 282,
"elevation_gain": 41
},
{
"coordinates": {
"coordinates": [
85.06494445,
25.6147376
],
"type": "Point"
},
"speed": 39,
"altitude": 130,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:42.115",
"metadata": null,
"distance": 1424.01,
"duration": 284,
"elevation_gain": 42
},
{
"coordinates": {
"coordinates": [
85.06503091,
25.61491977
],
"type": "Point"
},
"speed": 39,
"altitude": 128.43,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:44.000",
"metadata": null,
"distance": 1446.06,
"duration": 285,
"elevation_gain": 42
},
{
"coordinates": {
"coordinates": [
85.06511283,
25.61510362
],
"type": "Point"
},
"speed": 39,
"altitude": 129.57,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:46.054",
"metadata": null,
"distance": 1468.11,
"duration": 287,
"elevation_gain": 43
},
{
"coordinates": {
"coordinates": [
85.06519253,
25.61528579
],
"type": "Point"
},
"speed": 39,
"altitude": 128.22,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:48.054",
"metadata": null,
"distance": 1489.9,
"duration": 289,
"elevation_gain": 43
},
{
"coordinates": {
"coordinates": [
85.06527387,
25.6154717
],
"type": "Point"
},
"speed": 39,
"altitude": 127.24,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:50.034",
"metadata": null,
"distance": 1512.14,
"duration": 290,
"elevation_gain": 43
},
{
"coordinates": {
"coordinates": [
85.0653552,
25.6156576
],
"type": "Point"
},
"speed": 39,
"altitude": 128.53,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:52.010",
"metadata": null,
"distance": 1534.38,
"duration": 291,
"elevation_gain": 45
},
{
"coordinates": {
"coordinates": [
85.06546331,
25.6159047
],
"type": "Point"
},
"speed": 35,
"altitude": 127.5,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:55.108",
"metadata": null,
"distance": 1563.95,
"duration": 294,
"elevation_gain": 45
},
{
"coordinates": {
"coordinates": [
85.06557565,
25.61615026
],
"type": "Point"
},
"speed": 35,
"altitude": 126.02,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:34:58.035",
"metadata": null,
"distance": 1593.51,
"duration": 296,
"elevation_gain": 45
},
{
"coordinates": {
"coordinates": [
85.06566061,
25.61633543
],
"type": "Point"
},
"speed": 29,
"altitude": 126.06,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:01.010",
"metadata": null,
"distance": 1615.81,
"duration": 298,
"elevation_gain": 45
},
{
"coordinates": {
"coordinates": [
85.06574934,
25.61652881
],
"type": "Point"
},
"speed": 27,
"altitude": 124.9,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:04.062",
"metadata": null,
"distance": 1639.1,
"duration": 301,
"elevation_gain": 45
},
{
"coordinates": {
"coordinates": [
85.06583606,
25.61671781
],
"type": "Point"
},
"speed": 27,
"altitude": 125.89,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:07.030",
"metadata": null,
"distance": 1661.86,
"duration": 303,
"elevation_gain": 46
},
{
"coordinates": {
"coordinates": [
85.06592368,
25.61690647
],
"type": "Point"
},
"speed": 27,
"altitude": 125.79,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:10.019",
"metadata": null,
"distance": 1684.62,
"duration": 305,
"elevation_gain": 46
},
{
"coordinates": {
"coordinates": [
85.06601764,
25.61710781
],
"type": "Point"
},
"speed": 32,
"altitude": 127.84,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:13.039",
"metadata": null,
"distance": 1708.93,
"duration": 308,
"elevation_gain": 48
},
{
"coordinates": {
"coordinates": [
85.06613094,
25.61735059
],
"type": "Point"
},
"speed": 36,
"altitude": 127.83,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:16.005",
"metadata": null,
"distance": 1738.25,
"duration": 310,
"elevation_gain": 48
},
{
"coordinates": {
"coordinates": [
85.06624213,
25.61759282
],
"type": "Point"
},
"speed": 36,
"altitude": 125.88,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:19.022",
"metadata": null,
"distance": 1767.43,
"duration": 313,
"elevation_gain": 48
},
{
"coordinates": {
"coordinates": [
85.06631701,
25.61776256
],
"type": "Point"
},
"speed": 36,
"altitude": 126.07,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:21.013",
"metadata": null,
"distance": 1787.76,
"duration": 314,
"elevation_gain": 48
},
{
"coordinates": {
"coordinates": [
85.06639542,
25.61794028
],
"type": "Point"
},
"speed": 39,
"altitude": 127.75,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:23.027",
"metadata": null,
"distance": 1809.05,
"duration": 316,
"elevation_gain": 50
},
{
"coordinates": {
"coordinates": [
85.06647734,
25.61812598
],
"type": "Point"
},
"speed": 39,
"altitude": 127.96,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:25.079",
"metadata": null,
"distance": 1831.29,
"duration": 318,
"elevation_gain": 50
},
{
"coordinates": {
"coordinates": [
85.06655628,
25.61830491
],
"type": "Point"
},
"speed": 37,
"altitude": 128.07,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:27.089",
"metadata": null,
"distance": 1852.72,
"duration": 320,
"elevation_gain": 50
},
{
"coordinates": {
"coordinates": [
85.06666323,
25.61854686
],
"type": "Point"
},
"speed": 33,
"altitude": 126.67,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:30.067",
"metadata": null,
"distance": 1881.71,
"duration": 322,
"elevation_gain": 50
},
{
"coordinates": {
"coordinates": [
85.06677069,
25.61877522
],
"type": "Point"
},
"speed": 33,
"altitude": 124.07,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:33.186",
"metadata": null,
"distance": 1909.32,
"duration": 325,
"elevation_gain": 50
},
{
"coordinates": {
"coordinates": [
85.06686524,
25.61897614
],
"type": "Point"
},
"speed": 27,
"altitude": 125.17,
"activity": "MOVING",
"recorded_at": "2022-03-04T07:35:36.054",
"metadata": null,
"distance": 1933.61,
"duration": 327,
"elevation_gain": 51
},
{
"coordinates": {
"coordinates": [
85.06689824,
25.61904625
],
"type": "Point"
},
"speed": 0,
"altitude": 126.05,
"activity": "STOP",
"recorded_at": "2022-03-04T07:35:37.382",
"metadata": null,
"distance": 1942.08,
"duration": 328,
"elevation_gain": 52
}
],
"is_local": false
}
}
{
"code" : 404,
"message" : "object_not_found",
"description": "The requested object does not exist or already deleted.",
"errors" : [ ]
}
curl --location --request GET 'https://api.roam.ai/v2/trips/6221bf4393ade81ce90c8c5c/summary' \
--header 'Authorization: Bearer 07XXXX2fd55XXX0c6a58ab7101a9f5fa2'