Gruntify Api (v4.3)

The Gruntify API is organized around REST. Our API has predictable, resource-oriented URLs, and uses HTTP response codes to indicate API errors. We use built-in HTTP features, like HTTP authentication and HTTP verbs, which are understood by off-the-shelf HTTP clients.

JSON (application/json) is returned by all API responses.

The Gruntify API server is currently

The API is versioned using a three part version number as shown below.

Version Diagram

Figure 1: Version Format

Core Concepts

For more information on how these features described below work, the user tutorials are available on

Gruntify comes in three flavors. Gruntify SaaS supports Professional and Business subscriptions. The Business subscriptions offers more features than the Professional level, but people with the Professional option can add features as an “add-on”.

Enterprise subscriptions are based on a Professional or Business functionality set, then customized to include the features desired by customers.

To support this model, each Workspace has a set of feature flags which are turned on/off as needed and billed appropriately. So, when using the API for any workspace, you need to check which features are supported by this workspace. For example, only use the job-related API for a workspace with job feature enabled.

All entities, apart from the workspace entities themselves and some authentication entities are related to a single workspace. This includes the standard user records. Therefore, most calls include the workspace as part of the path. You cannot search for entities across workspaces. For example, if a company had two workspaces, you cannot search for the forms in both workspaces at once - rather you do two calls, one for each workspace.

In each workspace you can have Users, which can then be assigned to Teams. Depending on the complexity of the tasks, the field staff's work is recorded in a Request or a Job. Every Request and Job has a location, set either as a Latitude/Longitude pair or related to an Asset.


A Workspace is a top-level organizational entity. User access is configured on a per-workspace basis and only Users with the appropriate access in a Workspace can access the data within it.

Teams and Users

Users define the permission an Account has within the Workspace. The User can have Roles, Accreditations and Teams configured. An Account can be part of multiple Workspaces and can have different permissions in each one.

Teams are a group of users. Forms can be restricted to particular teams which is useful if different teams complete different jobs in your organization. A team's accreditations are the team members' accreditations.


Forms define a template for Requests and Jobs, as well as associated permissions (e.g., which Teams can access the Form) and other configuration. They are also used as templates for Assets and Reports.


A request may a record of a visit, an inspection, a request for work to be completed. Essentially a request has a form to be completed. They start as Created, and can become either Accepted or Rejected. Requests are assigned to an individual user.

Jobs (Business/Enterprise)

Jobs are like Requests, but they can have a more complex workflow and can be allocated to field staff on the basis of the skills required, equipment required and can be connected to your organization’s Assets for location. They also support automatic time tracking and can be made a repeating job using a recurring schedule. Jobs are assigned to a team.

  • Accreditations are the officially recognized skills of the users.
  • Assets are a geographically based records that model real-world entities, such as garden beds, roads, or power poles.
  • Equipment covers the trucks, machinery, computers, and any other tools owned by the organization. Equipment is associated with a Team that uses the equipment, and the Depot where it is stored.
  • Depots are locations associated with Teams and Equipment.

Form Ids and Versioning

Forms are integral to many parts of Gruntify so it is important to understand how the form versioning works. We keep each form version to ensure data consistency and integrity.

The Form Id field is a composite of the FormId and the Version from the Form entity. Version numbering starts at 1.

When you go to make a change to a form, you need to save any changes as draft.

Once you are happy that the changes are correct, the form is published and the version number is incremented. Therefore to find data that matches a particular form, you should join on both the form id and the version.

In another entity appears the ids appear as:

"Form": {
    "Id": "e3fc3a56-3bad-480c-811c-79781304a255",
    "Version": 1

In the Form entity:

"FormId": "e3fc3a56-3bad-480c-811c-79781304a255",
"FormVersion": 1,
"Id": "e3fc3a56-3bad-480c-811c-79781304a255:1",

Listing, Searching and Paging

There are three main ways of asking for one or more records and they follow standard naming patterns. Where entities do not follow this pattern, the same principles apply just the path may be a little different.

ID based access: Retrieve a single entity instance.

GET $gruntify_api_server/workspaces/<workspace>/<entity>/<entity id>/

For example, to get a particular user, append the user id to the users path. The user id is formatted as “auth0|


List All: Retrieve all entity instances.

GET $gruntify_api_server/workspaces/<workspace>/<entity>/

For example, to get all forms call


Search: Retrieve entity instances based on criteria

POST $gruntify_api_server/workspaces/<workspace>/<entity>/search/

Include a JSON body containing the search criteria. The criteria contains the paging details as well as the same as the fields in the entity for the actual search.

For example, to get all forms that related to Jobs, call $gruntify_api_server/workspaces/<workspace>/forms/search/ with the body

    formTitle: null,
    type: “Job”,
    status: "Published",
    pageToken: "eyJwYWdlU2l6ZSI6MTAsInBhZ2UiOjJ9"    

Where pageToken is of the format “{"Page":2, "PageSize":10}” base64 encoded (typically done using JSON.Stringfy). The response will include the fields

    "currentPage": 2,
    "previousPageToken": "eyJQYWdlU2l6ZSI6MTAsIlBhZ2UiOjF9",
    "nextPageToken": null

Use the previousPageToken and nextPageToken values in the pageToken entry in the body of the next search call to retrieve the previous and next pages.


Bearer Authentication

The API uses Bearer token Authentication/Authorization. The Authenticate endpoint returns a token that needs to be passed to requests in an Authorization header.

All API requests must be made over HTTPS.

The username and password are for a standard Gruntify account, the same you would use to log in to the web app. Once you have the Bearer token you are ready to make your API calls.

There are also single sign on access points used for the mobile clients but they are processed separately.

Authentication Request Parameters

ID Value
Auth0 Client Id 6JCsD3fJwFQstA32GLC2SIq4CRFGXrPo
Auth0 Domain
Grant Type
Realm Prod

Authentication Header

Once authenticated, all following calls require a header with the token received from the authentication call.

Authorization = "Bearer $token"

Powershell Example

$gruntify_api_server  = ""
$auth_body = @{
    grant_type = ""
    client_id = "6JCsD3fJwFQstA32GLC2SIq4CRFGXrPo"
    audience = ""
    username = "<Gruntify User Email Address>"
    password = "<Gruntify Password>"
    realm = "Prod"
    scope = "offline_access"
$auth_uri = ""
$auth_result = Invoke-RestMethod -method post -uri $auth_uri -Body $auth_body
$token = $auth_result.access_token
$headers = @{Authorization = "Bearer $token"}
$headers = $headers[-1]

$workspace = "beautiful_homes"
$result = Invoke-RestMethod -uri "$gruntify_api_server/workspaces/$workspace" -Headers $headers
Write-Host "Workspace details for $workspace"
Write-Host $result;

Figure 2: Sample Powershell Script for Authentication.

Security Scheme Summary

Security Scheme Type HTTP
HTTP Authorization Scheme bearer

Access Management


query Parameters
Request Body schema: application/json


Request samples

Content type