REST API Developer Guide

Using REST API you can integrate VEZMA (and all collected data) into your own software solution.

What is REST API? REST API defines a set of functions to which the developers can perform requests and receive responses. The interaction is performed via the HTTP protocol. An advantage of such an approach is the wide usage of HTTP. That is why REST API can be used practically for any programming language.

Common characteristics of VEZMA REST API resources are as follows:

  • You access the resource by sending an HTTP request to the VEZMA API server. The server replies with a response that contains either the data you requested, or the status indicator, or even both.
  • All resources are located at https://app.vezma.com/api/v1/
  • All resources may return different HTTP status codes (e.g., HTTP Status Code 200 for success response or HTTP Status Code 400 for the bad request).
  • You request a particular resource by adding a particular path to the base URL that specifies the resource.

Authenticating REST Requests 

Authentication is the process of proving your identity to the system. Identity is an important factor in VEZMA access control decisions. Requests are allowed or denied in part based on the identity of the requester.

HTTP header

The VEZMA REST API uses a custom HTTP scheme based on a Basic access authentication. It doesn't require cookies, session identifier nor login pages. VEZMA REST API however does not use login:password pair, but a shared secret calledtoken.

Custom authentication HTTP header is formed as follows:

Authorization: VEZMA {token}

Example of authentication HTTP request:

GET /api/v1/Version HTTP/1.1
Host: app.vezma.com
Authorization: VEZMA ABC123ABC123ABC123ABC123

Example using curl:

curl -X GET -H "Authorization: VEZMA ABC123ABC123ABC123ABC123" "https://app.vezma.com/api/v1/Version"

When the system receives an authenticated request, it fetches the token that you claim to have and uses it identify VEZMA company account. If the token do not match VEZMA records, the request is dropped and the system responds with an error message.

Alternative HTTP header

If you, for any reason, can not use standard Authorization HTTP header, you can use alternative X-Auth-Token HTTP header instead.

Example request:

GET /api/v1/Version HTTP/1.1
Host: app.vezma.com
X-Auth-Token: ABC123ABC123ABC123ABC123

Example using curl:

curl -X GET -H "X-Auth-Token: ABC123ABC123ABC123ABC123" "https://app.vezma.com/api/v1/Version"

Secure HTTP

VEZMA REST API requires, that you always use https (HTTP Secure protocol). Using standard HTTP is not allowed.

How to get token

Token can be generated after signing into VEZMA web application in SETTINGS -> REST API TOKEN. You need to be an company administrator to do this.

Response type and formats used in VEZMA REST API 

  • All VEZMA REST API responses are in JSON format and use UTF-8 character encoding
  • Date and time values are always in UTC timezone in ISO 8601 format
  • Vehicle speeds are in km/h * 10
    • Example: speed 455 means 45.5 km/h
  • Geographic positions are in WSG84 (World Geodetic System) aka EPSG:4326
    • Example: position Latitude = 48.856 and Longitude = 2.353 is in Paris (France)
  • Vehicle odometers, distances and radiuses are in meters
    • Example: vehicle odometer = 1600 is 1.6 km
  • Time durations and time-spans are in seconds
    • Example: duration = 3612 is 1 hour 0 minutes and 12 seconds
  • Money values are always in currency selected by a company administrator
  • Vehicle fueling/economy units are in litres

Using cursors to navigate collections 

The VEZMA REST API utilizes a technique called cursoring to paginate large result sets. Cursoring separates results into pages (the size of which are defined by the count request parameter) and provides a means to move backwards through these pages.

To retrieve cursored results, you initially pass a cursor with a value of -1 to the endpoint. By default, an API endpoint that supports cursoring will assume -1 was passed as cursor if you do not provide one. The response to a cursored request will contain nextCursor value.

The nextCursor is the cursor that you should send to the endpoint to receive the next batch of responses. You will know that you have requested the last available page of results when the API responds with a nextCursor = 0.

There is a great article and examples of using cursors in Twitter REST API documentations, which is very similar to ours.

Rate Limiting 

Rate limits are determined globally for the entire application. Every method allows you to make 180 requests per time window — on behalf of your application. One time window is considered as 15 minute interval.

Tips to avoid being Rate Limited

  • Caching. We recommend that you cache API responses in your application or on your site. For example, don't try to call the VEZMA REST API on every page load of your hugely popular website. Instead, call our API once a minute and save the response to your local server, displaying your cached version on your site. Refer to the Terms of Service for specific information about caching limitations.
  • Rate limiting by active user. If your site keeps track of many VEZMA users (for example, fetching their current positions), please consider only requesting data for users who have recently signed in to your site.
  • Request only what you need, and only when you need it.

These are just some example strategies.

Blacklisting

We ask that you honor the rate limit. If you or your application abuses the rate limits we will blacklist it. If you are blacklisted you will be unable to get a response from the VEZMA REST API. If you or your application has been blacklisted and you think there has been an error you can contact the email address on our Support page.

Technical support, contacts and future versions 

VEZMA REST API is a living organism. We will extend REST API over time. If you have any technical question and/or suggestion regarding REST API, please contact us at our technical support email address - dev@workinfield.com. Please use "VEZMA REST API" keywords somewhere in your email's subject line.

REST API reference

Users 

All members linked to company account.

GET /api/v1/Users

Returns all VEZMA user details including deactivated accounts.

Request:

GET /api/v1/Users HTTP/1.1

Response example:

[
    {
        "uid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
        "fullName": "Jan Pal",
        "email": "janpal@acme.com",
        "phoneNumber": "+1 (415) 230-0576",
        "createdOnUtc": "2013-05-20T13:52:08.917Z",
        "activatedOnUtc": "2013-06-14T12:11:14.983Z",
        "deactivatedOnUtc": null,
        "isAdministrator": true,
        "lastWeelkyReportSentOnUtc": "2014-04-24T08:29:43.915Z"
    },
    {
        "uid": "23456789-645f-447b-bbb6-f51af5951056",
        "fullName": "John Doe",
        "email": "johndoe@acme.com",
        "phoneNumber": "+421 948 290 869",
        "createdOnUtc": "2013-06-13T09:16:29.91Z",
        "activatedOnUtc": "2013-06-21T10:15:42.203Z",
        "deactivatedOnUtc": "2014-01-24T10:30:13.28Z",
        "isAdministrator": false,
        "lastWeelkyReportSentOnUtc": "2013-11-19T15:15:16.332Z"
    }
]

GET /api/v1/Users/{uid}

Returns specific VEZMA user details.

Request:

GET /api/v1/Users/12345678-40f3-46f1-b916-2048ae8ea6ec HTTP/1.1

Response example:

{
    "uid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
    "fullName": "Jan Pal",
    "email": "janpal@acme.com",
    "phoneNumber": "+1 (415) 230-0576",
    "createdOnUtc": "2013-05-20T13:52:08.917Z",
    "activatedOnUtc": "2013-06-14T12:11:14.983Z",
    "deactivatedOnUtc": null,
    "isAdministrator": true,
    "lastWeelkyReportSentOnUtc": "2014-04-24T08:29:43.915Z"
}

GET /api/v1/UsersPositions

Returns VEZMA users last known geo positions. Users with unknown last positions will not be in this list.

Request:

GET /api/v1/UsersPositions HTTP/1.1

Response example:

[
    {
        "uid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
        "positionLon": 2.353,  // Longitude
        "positionLat": 48.856, // Latitude
        "positionRecordedOnUtc": "2013-07-20T12:29:00Z",
        "positionIsOld": true,
        "online": false,
        "onlineRecordedOnUtc": "2013-07-20T12:29:00Z",
        "speed": 455 // 45.5 km/h
    },
    {
        "uid": "23456789-645f-447b-bbb6-f51af5951056",
        "positionLon": null,
        "positionLat": null,
        "positionRecordedOnUtc": null,
        "positionIsOld": true,
        "online": false,
        "onlineRecordedOnUtc": "2001-01-01T00:00:00Z",
        "speed": null
    }
]

GET /api/v1/UsersPositions/{uid}

Returns specific VEZMA users last known geo position.

Request:

GET /api/v1/UsersPositions/12345678-40f3-46f1-b916-2048ae8ea6ec HTTP/1.1

Response example:

{
    "uid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
    "positionLon": 2.353,  // Longitude
    "positionLat": 48.856, // Latitude
    "positionRecordedOnUtc": "2013-07-20T12:29:00Z",
    "positionIsOld": true,
    "online": false,
    "onlineRecordedOnUtc": "2013-07-20T12:29:00Z",
    "speed": 455 // 45.5 km/h
}

Vehicles 

All vehicles linked to company account.

GET /api/v1/Vehicles

Returns all VEZMA vehicle details excluding deleted vehicles.

Request:

GET /api/v1/Vehicles HTTP/1.1

Response example:

[
    {
        "vehicleId": 3,
        "name": "Mercedes",
        "note": "Best car in company",
        "odometer": 1600, // 1.6 km
        "odometerUpdatedOnUtc": "2014-03-27T09:10:09.92Z"
    },
    {
        "vehicleId": 4,
        "name": "Beetle",
        "note": "Smallest car in company",
        "odometer": 2963,
        "odometerUpdatedOnUtc": "2013-11-05T14:23:47.207Z"
    }
]

GET /api/v1/Vehicles/{id}

Returns specific VEZMA vehicle details.

Request:

GET /api/v1/Vehicles/3 HTTP/1.1

Response example:

{
    "vehicleId": 3,
    "name": "Mercedes",
    "note": "Best car in company",
    "odometer": 1600, // 1.6 km
    "odometerUpdatedOnUtc": "2014-03-27T09:10:09.92Z"
}

GET /api/v1/VehicleServices

Returns all vehicle services defined in company.

Request:

GET /api/v1/VehicleServices HTTP/1.1

Response example:

[
    {
        "serviceId": 1,
        "serviceName": "A/C System",
        "isDeleted": false
    },
    {
        "serviceId": 1220,
        "serviceName": "Air filter",
        "isDeleted": false
    },
    {
        "serviceId": 1227,
        "serviceName": "Battery",
        "isDeleted": false
    }
]

Places 

All frequently visited places and locations linked to company account.

GET /api/v1/Places

Returns all Places excluding deleted.

Request:

GET /api/v1/Places HTTP/1.1

Response example:

[
    {
        "placeId": 3,
        "name": "Home",
        "address": "Home, Street 12, City, State, Country",
        "radius": 13,     // in meters
        "lon": 17.107147, // Longitude
        "lat": 48.146     // Latitude
    },
    {
        "placeId": 7,
        "name": "Paris",
        "address": "75004 Paris, France",
        "radius": 45.72,
        "lon": 2.351564,
        "lat": 48.856852
    }
]

GET /api/v1/Places/{placeId}

Returns specific Place details.

Request:

GET /api/v1/Places/3 HTTP/1.1

Response example:

{
    "placeId": 3,
    "name": "Home",
    "address": "Home, Street 12, City, State, Country",
    "radius": 13,
    "lon": 17.107147,
    "lat": 48.146
}

Purposes 

All trip purposes in company account.

GET /api/v1/Purposes

Returns all purposes including deleted ones.

Request:

GET /api/v1/Purposes HTTP/1.1

Response example:

[
    {
        "purposeId": 1,
        "name": "Business",
        "isDeleted": false
    },
    {
        "purposeId": 1265,
        "name": "Private",
        "isDeleted": false
    },
    {
        "purposeId": 1266,
        "name": "Medical",
        "isDeleted": false
    },
    {
        "purposeId": 1267,
        "name": "Moving",
        "isDeleted": false
    },
    {
        "purposeId": 1268,
        "name": "Charity",
        "isDeleted": false
    }
]

Trips

All trips in company account.

GET /api/v1/Trips

Returns a cursored collection of all tracks.

Results are ordered with the most recent track first. Results are given in groups of MAX 50 tracks and multiple "pages" of results can be navigated through using the nextCursor value in subsequent requests. See Using cursors to navigate collections for more information.

Parameters:

  • count - Specifies the number of tracks attempt retrieval of, up to a maximum of 50 per distinct request. The value of count is best thought of as a limit to the number of results to return. When using the count parameter with this method, it is wise to use a consistent count value across all requests.
  • cursor - Causes the list of tracks to be broken into pages of no more than 50 at a time. The number of tracks returned is not guaranteed to be 50. If no cursor is provided, a value of -1 will be assumed, which is the first "page."

Request (first page):

GET /api/v1/Trips?count=2&cursor=-1 HTTP/1.1

Response example:

{
    "nextCursor": "fbacef28-cb7f-4a08-bb14-168eb5602379",
    "tracks": [
        {
            "tid": "49e89260-9099-46a8-9551-632a74c0ab91",
            "purposeId": 1,
            "purposeName": "Business",
            "note": "My first trip",
            "driverUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
            "vehicleId": 3,
            "inProgress": false,
            "isPrivate": false,
            "distanceMeasured": 123000, // in meters
            "distanceTotal": 123000,    // in meters
            "duration": 3612,           // in seconds
            "start": {
                "recordedOnUtc": "2014-06-04T11:32:00Z",
                "odometerMeasured": 5000, // in meters
                "odometerAdjusted": null, // in meters
                "odometer": 5000,         // in meters
                "reason": "InAppButton",
                "addressLong": "75004 Paris, France",
                "addressCustom": null,
                "placeId": 3,
                "lon": 17.107147,
                "lat": 48.146
            },
            "end": {
                "recordedOnUtc": "2014-06-04T12:44:00Z",
                "odometerMeasured": 123800,
                "odometerAdjusted": null,
                "odometer": 123800,
                "reason": "InAppButton",
                "addressLong": "75020 Paris, France",
                "addressCustom": null,
                "placeId": null,
                "lon": 17.907147,
                "lat": 48.946
            }
        },
        {
            "tid": "72b71f05-c911-4ee5-b673-146ba230fb5b",
            "purposeId": 1,
            "purposeName": "Business",
            "note": "* Private trip",
            "driverUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
            "vehicleId": 3,
            "inProgress": false,
            "isPrivate": true,
            "distanceMeasured": 12000,
            "distanceTotal": 12000,
            "duration": 600,
            "start": {
                "recordedOnUtc": "2014-05-29T13:58:00Z",
                "odometerMeasured": 0,
                "odometerAdjusted": null,
                "odometer": 0,
                "reason": "InAppButton",
                "addressLong": "* Private trip",
                "addressCustom": "* Private trip",
                "placeId": null,
                "lon": null,
                "lat": null
            },
            "end": {
                "recordedOnUtc": "2014-05-29T14:08:00Z",
                "odometerMeasured": null,
                "odometerAdjusted": null,
                "odometer": null,
                "reason": "InAppButton",
                "addressLong": "* Private trip",
                "addressCustom": "* Private trip",
                "placeId": null,
                "lon": null,
                "lat": null
            }
        }
    ]
}

Request (next page):

GET /api/v1/Trips?count=2&cursor=fbacef28-cb7f-4a08-bb14-168eb5602379 HTTP/1.1

Response example (truncated):

{
    "nextCursor": "0", // zero means last "page"
    "tracks": [
        {
            "tid": "fbacef28-cb7f-4a08-bb14-168eb5602379",
            "purposeId": null,
            "purposeName": "Very first trip",
            ...
        }
    ]
}

GET /api/v1/Trips/{tid}

Returns specific trip details.

Request:

GET /api/v1/Trips/49e89260-9099-46a8-9551-632a74c0ab91 HTTP/1.1

Response example:

{
    "tid": "49e89260-9099-46a8-9551-632a74c0ab91",
    "purposeId": 1,
    "purposeName": "Business",
    "note": "My first trip",
    "driverUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
    "vehicleId": 3,
    "inProgress": false,
    "isPrivate": false,
    "distanceMeasured": 123000, // in meters
    "distanceTotal": 123000,    // in meters
    "duration": 3612,           // in seconds
    "start": {
        "recordedOnUtc": "2014-06-04T11:32:00Z",
        "odometerMeasured": 5000, // in meters
        "odometerAdjusted": null, // in meters
        "odometer": 5000,         // in meters
        "reason": "InAppButton",
        "addressLong": "75004 Paris, France",
        "addressCustom": null,
        "placeId": 3,
        "lon": 17.107147,
        "lat": 48.146
    },
    "end": {
        "recordedOnUtc": "2014-06-04T12:44:00Z",
        "odometerMeasured": 123800,
        "odometerAdjusted": null,
        "odometer": 123800,
        "reason": "InAppButton",
        "addressLong": "75020 Paris, France",
        "addressCustom": null,
        "placeId": null,
        "lon": 17.907147,
        "lat": 48.946
    }
}

Expenses

All expenses in company account.

GET /api/v1/Expenses

Returns a cursored collection of all expenses.

Results are ordered with the most recent expense first. Results are given in groups of MAX 50 expenses and multiple "pages" of results can be navigated through using the nextCursor value in subsequent requests. See Using cursors to navigate collections for more information.

Parameters:

  • count - Specifies the number of expenses attempt retrieval of, up to a maximum of 50 per distinct request. The value of count is best thought of as a limit to the number of results to return. When using the count parameter with this method, it is wise to use a consistent count value across all requests.
  • cursor - Causes the list of expenses to be broken into pages of no more than 50 at a time. The number of tracks returned is not guaranteed to be 50. If no cursor is provided, a value of -1 will be assumed, which is the first "page."

Request (first page):

GET /api/v1/Expenses?count=3&cursor=-1 HTTP/1.1

Response example:

{
    "nextCursor": "5a695e5c-34c5-4a61-8fed-aa0a4ee747b1",
    "expenses": [
        {
            "expenseId": "4d51c791-d850-4c61-bdb6-e9b2aa4d233d",
            "expenseType": "Service",
            "note": "Service after very long period",
            "vehicleId": 5,
            "odometer": 789000,
            "createdOnUtc": "2014-07-03T12:40:20.6Z",
            "spentOnUtc": "2014-07-03T12:40:00Z",
            "createdByUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
            "spentByUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
            "totalCost": 777,  // in currency defined by company
            "general": null,   // for General expense only
            "fuelUp": null,    // for FuelUp expense only
            "service": {       // for vehicle Service expense only
                "items": [
                    {
                        "serviceId": 1244,
                        "serviceName": "Fuel system",
                        "isDeleted": false
                    },
                    {
                        "serviceId": 1248,
                        "serviceName": "Inspection",
                        "isDeleted": false
                    },
                    {
                        "serviceId": 1249,
                        "serviceName": "Lights",
                        "isDeleted": false
                    }
                ]
            }
        },
        {
            "expenseId": "557820de-e397-4f84-a906-def0bd37cbe1",
            "expenseType": "FuelUp",
            "note": "Refueling my car",
            "vehicleId": 3,
            "odometer": 123457300,
            "createdOnUtc": "2014-07-02T08:52:23.527Z",
            "spentOnUtc": "2014-07-02T08:52:00Z",
            "createdByUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
            "spentByUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
            "totalCost": 85.18,
            "general": null,        // for General expense only
            "fuelUp": {             // for FuelUp expense only
                "unitCount": 56,    // in Liters
                "unitCost": 1.521,  // in currency defined by company
                "consuption": null,
                "isPartialFillUp": false,
                "missedPreviousFillUp": true
            },
            "service": null     // for vehicle Service expense only
        },
        {
            "expenseId": "335faa1a-4982-45ce-8daa-aa8edd95ce61",
            "expenseType": "General",
            "note": "My own general expense",
            "vehicleId": null,
            "odometer": null,
            "createdOnUtc": "2014-07-28T09:49:45.813Z",
            "spentOnUtc": "2014-07-02T06:00:00Z",
            "createdByUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
            "spentByUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
            "totalCost": 123.35,
            "general": {     // for General expense only
                "category": {
                    "categoryName": "Toll",
                    "categoryId": 1096,
                    "isDeleted": false
                }
            },
            "fuelUp": null,  // for FuelUp expense only
            "service": null  // for vehicle Service expense only
        }
    ]
}

Request (next page):

GET /api/v1/Expenses?count=3&cursor=5a695e5c-34c5-4a61-8fed-aa0a4ee747b1 HTTP/1.1

Response example (truncated):

{
    "nextCursor": "0",
    "expenses": [
        {
            "expenseId": "5a695e5c-34c5-4a61-8fed-aa0a4ee747b1",
            "expenseType": "Service",
            "note": null,
            "vehicleId": 3,
            "odometer": 123456000,
            "createdOnUtc": "2014-07-01T10:05:53.62Z",
            "spentOnUtc": "2014-07-01T10:05:00Z",
            "createdByUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
            "spentByUid": "12345678-40f3-46f1-b916-2048ae8ea6ec",
            "totalCost": 123,
            "general": null,
            "fuelUp": null,
            "service": {
                "items": [
                    {
                        "serviceId": 1225,
                        "serviceName": "Air filter",
                        "isDeleted": false
                    },
                    {
                        "serviceId": 1226,
                        "serviceName": "Battery",
                        "isDeleted": false
                    }
                ]
            }
        },
        ...
    ]
}

GET /api/v1/ExpenseCategories

Returns all general expense categories defined in company.

Request:

GET /api/v1/ExpenseCategories HTTP/1.1

Response example:

[
    {
        "categoryName": "Entertainment",
        "categoryId": 1,
        "isDeleted": false
    },
    {
        "categoryName": "Lodging",
        "categoryId": 1092,
        "isDeleted": false
    },
    {
        "categoryName": "Meal",
        "categoryId": 1093,
        "isDeleted": false
    }
]
Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.