GeoOp API (1.3)

Download OpenAPI specification:

GeoOp API

The GeoOp API allows developer to integrate GeoOp functionality into their mobile, network or desktop applications.


Overview

The API implements the REST architecture and provides an easy and intuitive way of communication with the GeoOp system via the HTTP protocol. By sending GET, POST, PATCH, and DELETE requests to various API endpoints it is possible to manipulate the corresponding data containers called items.

The API receives requests and responds in widely supported JSON format thus allowing the developers to write GeoOp-powered applications in almost any major programming language (such as Java, C#, C/C++, PHP, Perl, Python, Ruby, etc.) and for all major platforms, including Windows, Mac OS X, Linux, iPhone, Android and Windows Phone.

Examples

Here's a couple of examples to demonstrate how easy it is to use the API.

If we want to get a list of all registered users we simply send a GET request to the /users endpoint:

GET /users HTTP/1.1
Host: api.geoop.com
Authorization: Bearer oJ_7Hj.f-F3f.kL
X-Version: 1.3

And to create a new job we send a POST request with a JSON object containing job data to the /jobs endpoint:

POST /jobs HTTP/1.1
Host: api.geoop.com
Authorization: Bearer oJ_7Hj.f-F3f.kL
Content-Type: application/json
X-Version: 1.3

{
    "jobs": [
        {
            "client": {"id": 318},
            "status": {"id": 1},
            "account": {"id": 22},
            "title": "Sample Job"
        }
    ]
}

Getting Started

To start using the API you need to first register a developer account on this portal and then add a new application, which will be assigned a unique identifier and a secret (password).

With the application identifier and secret you can request access tokens from our Authentication Server and then use them to make API requests. In fact, you can generate sample tokens right on your account page and test the API requests in the API Demo section.

An of course on this portal you will find many articles that describe how exactly the API works, what kind of data you can manipulate and how to do that.

Authentication

An application willing to make requests to the GeoOp API will have to include an Authorization header with a unique access token so that each request can be authenticated and correct access permissions applied to that application.

The access token can be obtained from the GeoOp Authentication Server via the OAuth 2.0 protocol.

OAuth 2.0

OAuth 2.0 is an open authorisation protocol, which provides a way for a GeoOp user to delegate certain permissions to a third-party application without having to enter their credentials (login/password) via the application interface.

Roles

The protocol defines the following four roles:

  1. Resource Owner – a registered GeoOp user (employee, manager, company, administrator, etc.) or a system service.
  2. Resource Server – a GeoOp web server (https://api.geoop.com) with access to the GeoOp database.
  3. Client – a native or third-party application or website utilising the GeoOp API. Authentication Server – a GeoOp web server (https://login.geoop.com) responsible for authenticating incoming requests and issuing authorisation codes and access tokens (see below).

Client Types

A client can be one of the following types:

  1. Confidential – a client that is capable of keeping its credentials (client ID and client secret) confidential (e.g. third-party servers with restricted access).
  2. Public – a client that is not capable of keeping client credentials confidential (e.g. mobile/browser applications).

Grant types

The protocol provides four ways for a client to get an access token:

  1. Authorisation Code Grant – a client redirects resource owner to the login page, receives an authorisation code from it via a redirect link and exchanges it for an access token.
  2. Implicit Grant – a simplified (an less secure) method where the client receives the access token via the redirect link.
  3. Resource Owner Password Credentials Grant – the client does not redirect resource owner to the login page and provides a native login form instead. For security reasons, this grant type is not available for third-party applications.
  4. Client Credentials Grant – the client acts as an independent entity (i.e. not on the resource owner's behalf). Therefore, it uses its own credentials to receive the access token.

Using SSL/TLS Security Layer

Since access token acts as a session identifier and is used by the GeoOp Resource Server to load associated resource owner and client identities and permissions, it is crucial that this token is transferred only via a secured connection. Therefore, both the Authentication Server and the Resource Server require all requests to be made via a secured HTTPS connection.

See Also

OAuth 2 Website

RFC 6749 – OAuth 2 Specification

RFC 6750 – Bearer Token Usage Specification

Client Registration

For a third-party application to request an authorisation code, it has to be first registered with GeoOp and assigned a Client ID and Client Secret (password).

During the registration process the third-party application's (Client) developer has to provide the following information:

  1. General information (e.g. developer/company name, contact information, application name and description, etc.).
  2. Client type (confidential or public) – that is, specify whether their application is capable of securely storing Client/Owner credentials.
  3. Client profile (type of application – e.g. mobile app, browser app, server app, etc).
  4. Redirect URI – this will be used by the GeoOp Authentication Server to redirect users back to the application after successful authentication. If Client type is 'confidential' then only https:// URL schema must be allowed.

Endpoints

Authentication requests are processed by the GeoOp Authentication Server located at https://login.geoop.com. The endpoints provided by the server are described below.


User-Friendly Endpoints

These endpoints provide user-friendly visual interface for logging in to the GeoOp system and granting application permissions.

/

This is the server's login page. Note that this is not an entry point and is not designed to be accessed directly. server login

There are two possible scenarios of how the page can behave:

  1. A user manually opens the page in their browser or is redirected to it from another website. In this case the server silently redirects the user to the GeoOp application website.
  2. A user is redirected to this page from a /oauth2/code endpoint. In this case the server uses the existing authentication session generated by the /oauth2/code endpoint. It may show the login form if the user has not yet been authenticated or if the client has explicitly required manual user authentication. On successful authentication it redirects the user to a third-party website or application.

/grant

This is a page where a resource owner is presented with some basic information about the application (its name and developer) and a list of permissions that they can grant to that application (the latter is not yet implemented). grant access

If allowed by the application's developer, the resource owner may be able to choose which permissions they want to grant to the application.

OAuth 2 Endpoints

These endpoints allow third-party applications to request authorisation codes and/or access tokens utilising the OAuth 2.0 protocol.

/oauth2/code

An application that wants to get an authorisation code and later exchange it for an access token for GeoOp API has to redirect the resource owner to this endpoint.

Parameters accepted by the endpoint:

Name Required Description
client_id Required A unique client (application) identifier obtained from GeoOp.
response_type Required Must be code as per the RFC-6749 specification.
scope Required Space-delimited list of permissions scopes required by the client(application). If set to default the default permissions list set by the application's developer will be requested.

Currently the only supported value is default.
state Recommended An arbitrary string that will be returned by the authentication server back to the client (application). Using this string to correlate requests and responses may help prevent certain attacks, such as cross-site request forgery.
access_type Optional Determines whether the client (application) is intended to work in offline mode. If so, the Authentication Server may issue a refresh token, which, once the current access token expires, can be exchanged by the client for a new access token without resource owner's interaction with the Server.

Allowed values are online (default) and offline.
approval_prompt Optional Determines whether the resource owner's session may be used for automatic authentication.

Allowed values are auto (default) and force. Must be set to force if the client requires refresh token.

If set to auto, then the log in form will not be shown to the resource owner if they have already been authenticated by the Authentication Server and their current session is valid.

If set to force, then the user will be required to log in manually via the log in form, no matter whether they have already been authenticated by the Server.
redirect_uri Optional Determines where the resource owner is redirected to after successful log in. If provided, the value must exactly match one of the URIs registered by the application's developer.

/oauth2/token

This is a multi-purpose endpoint, but the ultimate goal of using it is to receive an access token. The following sections describe various ways of how that can be achieved.

Getting an access token via the implicit grant type flow

When an application wants the access token to be included into the redirect URI, then it may use the /oauth2/token endpoint to initiate an implicit grant type flow. It has to make a GET request to the endpoint and include the following parameters:

Name Required Description
client_id Required A unique client (application) identifier obtained from GeoOp.
response_type Required Must be implicit as per the RFC-6749 specification.
scope Required Space-delimited list of permissions scopes required by the client (application). If set to default the default permissions list set by the application's developer will be requested.

Currently the only supported value is default.
state Recommended An arbitrary string that will be returned by the authentication server back to the client (application). Using this string to correlate requests and responses may help prevent certain attacks, such as cross-site request forgery.
approval_prompt Optional Determines whether the resource owner's session may be used for automatic authentication.

Allowed values are auto (default) and force.

If set to auto, then the log in form will not be shown to the resource owner if they have already been authenticated by the Authentication Server and their current session is valid.

If set to force, then the user will be required to log in manually via the log in form, no matter whether they have already been authenticated by the Server.
redirect_uri Optional Determines where the resource owner is redirected to after successful log in. If provided, the value must exactly match one of the URIs registered by the application's developer.

Getting an access token via the client credentials grant type flow Not Implemented

When an application wants to receive an access token that should allow it to act on its own behalf (as a system task, for example), then it may use the /oauth2/token endpoint to initiate a client credentials grant type flow. It has to make a POST* request to the endpoint and include the following parameters:

Name Required Description
client_id Required† A unique client (application) identifier obtained from GeoOp.
client_secret Required† A client (application) secret obtained from GeoOp. This parameter may be omitted if the client's type is public.
grant_type Required Must be client_credentials as per the RFC-6749 specification.
scope Required Space-delimited list of permissions scopes required by the client (application). If set to default the default permissions list set by the application's developer will be requested.

Currently the only supported value is default.

* Please use application/x-www-form-urlencoded data encoding type when submitting POST requests. † These parameters may be omitted if the Authorization header is used for client authentication.

On success, a JSON object of the following format will be returned:

{
    "access_token": "2YotnFZFEjr1zCsicMWpAA",
    "token_type": "Bearer",
    "expires_in": 3600
}

On error, a JSON object of the following format will be returned:

{
    "error": "invalid_grant",
    "error_code": 2007,
    "error_description": "The client is not authorised to use the specified grant type."
}

Exchanging an authorisation code for an access token

Once the application has received an authorisation code as a parameter added to the redirect URI, it needs to exchange it for an access token, which it will then use to make requests to the GeoOp API. To do that, it has to make a POST* request to the /oauth2/token endpoint and include the following parameters:

Name Required Description
client_id Required† A unique client (application) identifier obtained from GeoOp.
client_secret Required† A client (application) secret obtained from GeoOp. This parameter may be omitted if the client's type is public.
grant_type Required Must be authorization_code as per the RFC-6749 specification.
code Required A one-time authorisation code received from the Server.
redirect_uri Optional Determines where the resource owner is redirected to after successful log in. If provided, the value must exactly match one of the URIs registered by the application's developer.
* Please use application/x-www-form-urlencoded data encoding type when submitting POST requests.
† These parameters may be omitted if the Authorization header is used for client authentication.

On success, a JSON object of the following format will be returned:

{
    "access_token": "2YotnFZFEjr1zCsicMWpAA",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
    "owner_id": 5482
}

On error, a JSON object of the following format will be returned:

{
    "error": "invalid_request",
    "error_code": 2012,
    "error_description": "No authorisation code provided."
}

Exchanging a refresh token for an access token

If the application has received a refresh token, it may use the /oauth2/token endpoint to exchange it for a new access token once the current access token has expired. To do that, it has to make a POST* request to the endpoint and include the following parameters:

Name Required Description
client_id Required† A unique client (application) identifier obtained from GeoOp.
client_secret Required† A client (application) secret obtained from GeoOp. This parameter may be omitted if the client's type is public.
grant_type Required Must be refresh_token as per the RFC-6749 specification.
refresh_token Required A refresh token received from the Server.
* Please use application/x-www-form-urlencoded data encoding type when submitting POST requests.
† These parameters may be omitted if the Authorization header is used for client authentication.

On success, a JSON object of the following format will be returned:

{
    "access_token": "2YotnFZFEjr1zCsicMWpAA",
    "token_type": "Bearer",
    "expires_in": 3600
}

On error, a JSON object of the following format will be returned:

{
    "error": "invalid_request",
    "error_code": 2021,
    "error_description": "No refresh token provided."
}

/oauth2/revoke

This endpoint is used to revoke an existing access/refresh token. It accepts just one parameter:

Name Required Description
token Required An access/refresh token that has to be revoked. If the specified token has a linked token of other kind, then both tokens will be revoked.

The endpoint always returns a JSON response.

On success, the HTTP code will be 200 and the format of the response object will be as follows:

{
    "revoked_token": "3a8dda76d511a1cec650d4379e4afdea"
}

On error, the HTTP code will be 400 and the format of the response object will be as follows:

    "error": "invalid_request",
    "error_code": 2020,
    "error_description": "The token parameter is invalid or missing."
}

Third-Party Server Application

Client Information

The Third-Party Server must be able to store its client secret securely. Since GeoOp does not control how that storage is implemented, it is required that any third-party willing for their server client to be assigned the confidential type must first apply for a certificate from GeoOp. The certification procedure allows GeoOp to assess whether the Third-Party Server meets its security standards.

For this article it is assumed that the Third-Party Server has successfully passed the certification procedure.

Client type Confidential
Provides Client ID
Client Secret
Grant type Authorization Code
Requests owner credentials No
Stores owner credentials No
Receives refresh token Yes (if requested)
Scope (permissions) Limited (defined by the developer)
Owner can control scope Yes (if allowed by the developer)

Authentication Process

The Third-Party Server is required to redirect resource owner to the GeoOp login page. Once authenticated by GeoOp, the resource owner then authorises the Third-Party Server to act on their behalf and grants it certain permissions (up to the limit allowed by the developer).

Initial Authentication

  1. The resource owner opens a third-party web page in their browser. The page is generated by the Third-Party Server: initial authentication

  2. The Third-Party Server redirects the resource owner to the GeoOp Authentication Server. It includes its client ID into the request URL and states the desired response type (must be code). It also provides a scope parameter (must be default). Optionally, it can include a state parameter and assign it any value:

GET /oauth2/code?response_type=code&client_id=s6BhdRkqt3&scope=default&state=xyz HTTP/1.1
Host: login.geoop.com
  1. The Authentication Server generates a login page and asks the resource owner to enter their credentials: third party login page

  2. The resource owner enters their credentials and clicks the 'Sign In' button.

  3. The Authentication Server authenticates the resource owner and loads information about the client based on the provided client ID.

  4. It then generates a page where the resource owner is presented with some basic information about the client and is asked to authorise the application to act on their behalf: third party app grant Note that the resource owner may not be allowed to select which permissions to grant to the client if that option has been disabled by the client developer.

  5. The resource owner submits the form and the Authentication Server generates a short-lived authorisation code and links the selected permissions, the resource owner ID and the client ID to it.

  6. Finally, the Authentication Server instructs the browser to redirect the resource owner back to the Third-Party Server via the registered redirect URI (which must use the HTTPS protocol) and adds the authorisation code to that URI. If the state parameter has been received in step 2, then its sanitised value is also added to the URI:

HTTP/1.1 302 Found
Location: https://example.com/demo/oauth?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
  1. The Third-Party Server generates a confirmation page and shows it to the resource owner:

third party redirect

  1. At the same time it makes a background request to the Authentication Server and provides it with its credentials and the authentication code:
POST /oauth2/token HTTP/1.1
Host: login.geoop.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw

OR (if the server prefers to use the Authorization header):

POST /oauth2/token HTTP/1.1
Host: login.geoop.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
  1. The Authentication Server authenticates the client (Third-Party Server) and loads the permissions and resource owner ID linked to the authorisation code.

  2. It then generates an access token and links the permissions and resource owner ID to that token.

  3. Finally, it returns the following response to the client (the refresh token may be omitted if it was not requested by the client in step 2 or if the resource owner opted for forced re-authentication of the client in step 6):

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"oJ_7Hj.f-F3f.kL",
  "token_type":"Bearer",
  "expires_in":3600,
  "refresh_token":"52hKUVsnDoy729Hdhi7ff"
}
  1. The Third-Party Server stores securely the access token and the refresh token (if there is any) and can now make direct API calls.

  2. It uses the data retrieved from the API Server to generate the application interface: demo app

On Access Token Expiration

If the Third-Party Server has NOT received a refresh token, then when the access token expires it has to obtain a new access token from the Authentication Server by following the above described procedure.

If the Third-Party Server has received the refresh token, then it can exchange that token for a new access token without having to ask the resource owner to re-authenticate it.

  1. The client makes a background request to the Authentication Server in the following format:
POST /oauth2/token HTTP/1.1
Host: login.geoop.com
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA&client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw

OR (if the server prefers to use the Authorization header):

POST /oauth2/token HTTP/1.1
Host: login.geoop.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
  1. The Authentication Server authenticates the client.

  2. It loads the permission set linked to the provided refresh token.

  3. It then generates a new access token and links the permission set to this new token.

  4. Finally, it returns a response in the following format:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"oJ_7Hj.f-F3f.kL",
  "token_type":"Bearer",
  "expires_in":3600
}
  1. The Third-Party Server stores securely the new access token and is now able to make API requests using this new token.

Making API Requests

Once the Third-Party Server has obtained the access token, it can make API calls to the GeoOP API Server. It must use the Authorization request header as in the example below:

Host: api.geoop.com
Authorization: Bearer mF_9.B5f-4.1JqM
X-Version: 1.0

Third-Party Public Application


Client Information

All clients that have not been certified by GeoOp are assumed to be of public type.

Client type Public
Provides Client ID
Grant type Authorization Code
Implicit
Requests owner credentials No
Stores owner credentials No
Receives refresh token No
Scope (permissions) Limited (defined by the developer)
Owner can control scope Yes (if allowed by the developer)

Authentication Process

Since full authentication of client is not required (it does not store client secret) it can choose between the following two grant types:

Authorisation Code Grant – recommended if client wants to make a background call to obtain an access token Implicit Code Grant – recommended when client does not want to make additional requests to obtain an access token (note that the access token may get exposed in this case)

Authorisation Code Grant

The Third-Party Application is required to redirect resource owner to the GeoOp login page. Once authenticated by GeoOp, the resource owner then authorises the Third-Party Application to act on their behalf and grants it certain permissions (up to the limit allowed by the developer).

  1. The application shows a welcome screen and asks the resource owner to sign in via the GeoOp website: app welcome screen

  2. The application launches a web browser (either embedded or an external browser application) and redirects the resource owner to the login page. It includes its client ID into the request URL and states the desired response type (must be code). It also provides a scope parameter (must be default). Optionally, it can include a state parameter and assign it any value:

GET /oauth2/code?response_type=code&client_id=s6BhdRkqt3&scope=default&state=xyz HTTP/1.1
Host: login.geoop.com
  1. The Authentication Server generates a login page and asks the resource owner to enter their credentials: app login screen

  2. The resource owner enters their credentials and clicks the 'Sign In' button.

  3. The Authentication Server authenticates the resource owner and loads information about the client based on the provided client ID.

  4. It then generates a page where the resource owner is presented with some basic information about the client and is asked to authorise the application to act on their behalf: app grant screen Note that the resource owner may not be allowed to select which permissions to grant to the client if that option has been disabled by the client developer.

  5. The resource owner submits the form and the Authentication Server generates a short-lived authorisation code and links the selected permissions, the resource owner ID and the client ID to it.

  6. Finally, the Authentication Server instructs the browser to redirect the resource owner back to the Third-Party Application via the registered redirect URI and adds the authorisation code to that URI. If the state parameter has been received in step 2, then its sanitised value is also added to the URI:

HTTP/1.1 302 Found
Location: application://oauth?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
  1. The Third-Party Application shows a confirmation screen to the resource owner: app confirmation screen

  2. At the same time it makes a background request to the Authentication Server and provides it with its credentials and the authentication code:

POST /oauth2/token HTTP/1.1
Host: login.geoop.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&client_id=s6BhdRkqt3
  1. The Authentication Server authenticates the client (Third-Party Application) and loads the permissions and resource owner ID linked to the authorisation code.

  2. It then generates an access token and links the permissions and resource owner ID to that token.

  3. Finally, it returns the following response to the client (note that public clients are not allowed to request or receive refresh token):

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"oJ_7Hj.f-F3f.kL",
  "token_type":"Bearer",
  "expires_in":3600
}
  1. The Third-Party Application stores the access token and can now make direct API calls.

  2. It uses the data retrieved from the API Server to generate the application interface: mobile app screen

Implicit Code Grant

The process is quite similar to the one described above, although it involves less steps, but is also less secure (as the access token may get exposed, for example, in the address bar of a browser).

  1. The application shows a welcome screen and asks the resource owner to sign in via the GeoOp website: mobile welcome screen

  2. The application launches a web browser (either embedded or an external browser application) and redirects the resource owner to the login page. It includes its client ID into the request URL and states the desired response type (must be token). It also provides a scope parameter (must be default). Optionally, it can include a state parameter and assign it any value:

GET /oauth2/token?response_type=token&client_id=s6BhdRkqt3&scope=default&state=xyz HTTP/1.1
Host: login.geoop.com
  1. The Authentication Server generates a login page and asks the resource owner to enter their credentials: mobile login screen

  2. The resource owner enters their credentials and clicks the 'Sign In' button.

  3. The Authentication Server authenticates the resource owner and loads information about the client based on the provided client ID.

  4. It then generates a page where the resource owner is provided with some basic information about the client and is asked to authorise the application to act on their behalf: mobile grant access Note that the resource owner may not be allowed to select which permissions to grant to the client if that option has been disabled by the client developer.

  5. The resource owner submits the form and the Authentication Server generates an access token and links the permissions and resource owner ID to that token.

  6. Finally, the Authentication Server instructs the browser to redirect the resource owner back to the Third-Party Application via the registered redirect URI and adds the access token to that URI. If the state parameter has been received in step 2, then its sanitised value is also added to the URI:

HTTP/1.1 302 Found
Location: application://oauth?token=oJ_7Hj.f-F3f.kL&token_type=Bearer&expires_in=3600&state=xyz
  1. The Third-Party Application stores the access token and can now make direct API calls.

  2. It uses the data retrieved from the API Server to generate the application interface: mobile app

On Access Token Expiration

Since public Third-Party Application cannot receive refresh token, when the access token expires it has to obtain a new access token from the Authentication Server by following either of the above described procedures.


Making API Requests

Once the application has obtained the access token, it can make API calls to the GeoOP API Server. It must use the Authorization request header as in the example below:

GET /jobs HTTP/1.1
Host: api.geoop.com
Authorization: Bearer oJ_7Hj.f-F3f.kL
X-Version: 1.0

API Requests


Endpoint URLs

The format of the API URL is very simple: https://api.geoop.com/:collection[/:item][/:action]

Variable Format Example Required Description
:collection [A-z]+ jobs Yes Collection name.
:item [0-9]+ 157 No Identifier of an entity within the collection.
:action [A-z]+ upload No Name of an action to be applied to a collection or an item (if specified).

Examples

Get the list of all jobs of a subscriber: GET https://api.geoop.com/jobs

Change information about user with ID 1234: PATCH https://api.geoop.com/users/1234

Upload a binary file: POST https://api.geoop.com/files/upload


Versioning

Since the request and response formats may change from one version of the API to another, you must specify the required version of the API in the X-Version header. If the specified version is invalid or outdated, then an error response will be returned.

The API will report its version in the X-Version response header.


Request Methods

Method Description Restrictions
GET Retrieve a list of items in a collection or an item with the specified ID within that collection. This method is not allowed for actions.
POST Create one or more items within the specified collection. Apply an action to the specified collection or item within that collection. This method is allowed only for collections and actions.
PATCH Update one or more items within the specified collection. This method is not allowed for actions.
DELETE Delete one or more items within the specified collection. This method is not allowed for actions.

The request method verb can be specified in a special X-Method header. This is a way to make correct requests for solutions that support only limited number of verbs (and do not allow making requests such as PATCH).

Note that the value specified in the header overwrites the actual type of the request. For example, a PATCH request with the X-Method header having the GET value will be interpreted by the API as a GET request.

Also note that it is not always possible to set the request body for the GET request. Therefore, when it is required to simulate PATCH and DELETE requests, it is recommended to use POST request with a custom X-Method header. Simply put, use GET for reading and POST for writing.

Request Modifiers

Modifiers are queries that affect the format of the response object. Note that all the below listed modifiers are valid only for GET requests.

By default (if no modifiers are applied), the response object will contain a maximum of 20 items sorted by the id field in ascending order and consisting of a pre-defined set of fields and associations.


Contents

The following modifiers are supported by the API at the moment:

  • Fields
  • Page
  • Where
  • Sort
  • Flags
  • Accept Associations

Fields

The fields modifier allows specifying a list of fields and/or associations that the response object(s) must contain.

Format Example Response Object Will Have Comments
wildcard ?fields=*
?fields=[]
All available fields.
All available associations with default formatting.
Simple (one-to-one) associations will be formatted as items. Complex associations will be formatted as collections of items.
comma-separated values ?fields=firstName,status Specified fields and/or associations + the id field. If any of the specified fields/associations does not exist within the collection, an error response will be returned.
nested ?fields=*,status[timestamp] All available fields + specified associations with requested formatting. Nested format can be applied only to associations.

It is possible to specify what fields/associations should be included into the association object by listing the required fields inside the square brackets []. Note that simple associations within the association object will always be formatted as items and complex associations – as collections of items.

Examples
Modifier Response Object Will Have
?fields=*,[] All fields and all associations with default formatting.
?fields=*,[*] All fields and all associations formatted as items or collections of items.
?fields=firstName,workgroups Fields id and firstName + workgroups association with default formatting.
?fields=phone,[] Fields id and phone + all associations formatted as a single item identifier or collections of item identifiers.
?fields=phone,[],workgroups[] Fields id and phone + workgroups association formatted as a collection of item identifiers + all other associations formatted as a single item identifier or collections of item identifiers.
?fields=phone,[*],workgroups[] Fields id and phone + workgroups association formatted as a collection of item identifiers + all other associations formatted as a single item or collections of items.
?fields=phone,[],workgroups[name] Fields id and phone + workgroups association formatted a collection of items (each of which containing the only id and name fields) + all other associations formatted as a single item identifier or collections of item identifiers.
?fields=phone,[],workgroups[name,customers[*]] Formatting error (nested brackets are not supported – nested associations will always be formatted as item identifiers or collections of item identifiers).
?fields=*,[],[*] Formatting error (square brackets must be either empty or containing the wildcard symbol).

Page

The page modifier allows splitting large numbers of collection items into several pages. This modifier can be applied only to collections.

Format Example Response Object Comments
one value ?page=3 The response object will contain the default number of records (items) per page. The default number is 20 records per page.
two values ?page=3,25 The response object will contain the specified number of records (items) per page. The maximum number of records per page cannot exceed 100.

The response object will always contain a metadata object with the following values:

Value Description
page Current page number.
pageCount Total number of pages.
recordsCount Total number of records available.
recordsPerPage Maximum number of records per each page.
Examples
Modifier Response Object Will Have
?page=15 A slice of collection containing records with index numbers from 301 to 320 (note that the index numbers are not the items' identifiers).
?page=15,5 A slice of collection containing records with index numbers from 76 to 80 (since now there are only 5 records per page).
?page=15,200 Parsing error (the maximum number of records per page cannot exceed 100).
?page=0 Formatting error (the page number must be positive).

Where

The where modifier allows specifying custom filtration criteria to be applied to a collection. This modifier can be applied only to collections. Note that not all fields/associations may support filtering.

Format Example Meaning
fieldName operator value [join operator] ?where=firstName is "John" Get only entities with field firstName equal to John
associationName.fieldName operator value [join operator] ?where=company.name startsWith "eco" Get only entities with field name of association company beginning with eco

The filters can be applied only to fields/associations that support filtering. Non-numeric values and lists must be put inside double quotes "" (use the backslash \ symbol to escape inner quotes).

The following operators are supported at the moment:

Operator Meaning Example Restrictions
=
==
is
eq
equalTo
Equal to ?where=firstName = "John"
?where=firstName == "John"
?where=firstName is "John"
?where=firstName eq "John"
?where=firstName equalTo "John"
!=
<>
isNot
neq
notEqualTo
Not equal to ?where=firstName != "John"
?where=firstName <> "John"
?where=firstName isNot "John"
?where=firstName neq "John"
?where=firstName notEqualTo "John"
>
gt
greaterThan
Greater than ?where=timestamp > 1372206671
?where=timestamp gt 1372206671
?where=timestamp greaterThan 1372206671 Only supported for numeric fields.
>=
gte
greaterThanOrEqualTo
Greater than or equal to ?where=timestamp >= 1372206671
?where=timestamp gte 1372206671
?where=timestamp greaterThanOrEqualTo 1372206671
Only supported for numeric fields.
<
lt
lessThan
Less than ?where=timestamp < 1372206671
?where=timestamp lt 1372206671
?where=timestamp lessThan 1372206671
Only supported for numeric fields.
<=
lte

lessThanOrEqualTo
Less than or equal to ?where=timestamp <= 1372206671
?where=timestamp lte 1372206671
?where=timestamp lessThanOrEqualTo 1372206671 Only supported for numeric fields.
~
contains
Contains ?where=firstName ~ "Jo"
?where=firstName contains "Jo"
Case-insensitive.
Not supported for numeric fields.
!~
notContains
Does not contain ?where=firstName !~ "Jo"
?where=firstName notContains "Jo" Case-insensitive.
Not supported for numeric fields.
~%
sw
startsWith
bw
beginsWith
Starts with ?where=firstName ~% "Jo"
?where=firstName sw "Jo"
?where=firstName startsWith "Jo"
?where=firstName bw "Jo"
?where=firstName beginsWith "Jo"
Case-insensitive.
Not supported for numeric fields.
%~
ew
endsWith
Ends with ?where=firstName %~ "Jo"
?where=firstName ew "Jo"
?where=firstName endsWith "Jo"
Case-insensitive.
Not supported for numeric fields.
^
in
One of ?where=id ^ (100, 102, 107)
?where=id in (100, 102, 107)
!^
nin
notIn
None of ?where=id !^ (100, 102, 107)
?where=id nin (100, 102, 107)
?where=id notIn (100, 102, 107)

The modifier allows using various functions for values. The list of supported functions is as follows:

Function Description Example Result
My(fieldName) Retrieve value of the specified field of the current user's identity object. My("firstName") John
LowerCase(value) Convert all characters of the value to lower case. LowerCase("Test") test
UpperCase(value) Convert all characters of the value to upper case. UpperCase("Test") TEST
Sum(value1, [value2, [...]]) Calculate a sum of all values in the list. Sum(1, 2, 3, 4) 10
Product(value1, [value2, [...]]) Calculate a product of all values in the list. Product(1, 2, 3, 4) 24
DateTime(year, [month,] [day,][hour,] [minute,] [second]) Convert a date into the Unix timestamp. DateTime(2013, 8, 23, 15, 52, 27) 1377229947
DateTimeFormat(time, [format]) Convert a date of the specified format into the Unix timestamp.
Supported formats: ISO8601, RFC822, RFC850, RFC1036, RFC2822, RFC3339, relative (this format supports natural-language time values like "now" or "-3 months").
DateTimeFormat("Fri, 23 Aug 2013 15:52:27 +1200", "RFC822")
DateTimeFormat("now", "relative")
1377229947
1377229947

Note that the modifier can contain more than one condition. The conditions can be joined together using the AND and OR join operators and can also be grouped using round brackets ().

Examples
Modifier Response Object Will Have
?where=job in (1123,1124,1130) A slice of collection containing records whose job field's value is either 1123, 1124 or 1130.
?where=firstName startsWith "Sam" A slice of collection containing records whose firstName field's value starts with Sam (case-insensitive). The following values satisfy that criteria: Sam, Samuel, Samantha. The following value, however, does not satisfy the criteria: Rosamund.
?where=firstName contains "Sam" AND firstName isNot "Sam" A slice of collection containing records whose firstName field's value contains text Sam (case-insensitive) and is not equal to Sam. The following values satisfy that criteria: Samuel, Samantha, Rosamund. The following values, however, do not satisfy the criteria (note the second condition): Sam, sam.
?where=(firstName contains "Sam" OR firstName startsWith "Rosa") AND timestamp < DateTimeFormat("-2 months", "relative") A slice of collection containing records whose firstName field's value contains text Sam (case-insensitive) or starts with text Rosa and whose date of creation was no later than two months before.

Sort

The sort modifier allows sorting the requested collection by specified fields and/or associations. The modifier can be applied only to collections. Note that not all fields/associations may support sorting.

Format Example Meaning Restrictions
fieldName ?sort=firstName Sort the entities by the value of the firstName field If sorting type is omitted, then the ascending sorting type will be applied by default.
fieldName[type] ?sort=firstName[desc] Sort the entities by the value of the firstName field in descending order The type value must be either asc (ascending order) or desc (descending order).

Flags

The flags modifier can enable special features. Multiple features can be enabled by listing features in a comma separated list.

Feature Name Example Meaning Restrictions
recordsCount ?flags=recordsCount Include a full metadata object on the request with the following values:
- page the page number within the set of records that has been returned
- recordsPerPage the maximum number of records returned in the request
- pagesCount the recordsPerPage / recordsCount
- recordsCount total count of the records identified in the request
It is advised that you only use the recordsCount flag on the first request as the performance cost can grow on very large data sets. Subsequent page requests need not use the flag.
accountSharing ?flags=accountSharing For accounts that are Partners with sub Child accounts, enabling this well return relevant data from all related accounts. Only available for Partners, a suitable scenario would be franchise reporting

Accept Associations

The Accept-Associations header, or accept-associations query parameter, can be used to modify the associations that are returned in the response. It accepts 2 values: all (default) and active, where all will cause the response to return all associations, whether they are active or deleted, and active will cause the response to only return active associations. Note that this only applies to entities that are soft deleted.

In Example Meaning
header Accept-Associations: all Return all associations
header Accept-Associations: active Return only active associations
query ?accept-associations=all Return all associations
query ?accept-associations=active Return only active associations

API Responses

An API response is a standard HTTP response containing a JSON object in the body.


Response Status Codes

Depending on whether the request has been successfully processed by the API server, the corresponding response may have one of the following HTTP status codes:

Code Meaning Description
200 Request was understood and processed The API Server understood the request and processed it successfully. Syntax of the request was fine.
400 Request was not understood Something is wrong with the request syntax. The API Server doesn't understand the request and hence cannot process it.
401 Missing or invalid client credentials The request cannot be processed because of missing/invalid client credentials.
403 Operation not permitted The client attempted to access an endpoint or an item without having sufficient permissions to do that.
404 Non-existing endpoint or item The client attempted to access an endpoint or an item that doesn't exist or that it doesn't have access to.
405 Request method is not allowed The client attempted to send a request of type that the endpoint in question doesn't support.
422 Request was not processed due to client error The request syntax was fine, but the content of the request included some invalid data that prevented the API Server from successfully processing it.
500 Request was not processed due to API error The API Server understood the request, but wasn't able to process it because of an unexpected error.

Response Types

The response object will always have a result property indicating whether the request has been processed and if the processing has been successful. Possible values of the property are:

Value Request Type Description
success GET requests
Other requests
The request has been processed successfully.

All incoming items from the request body have been processed and saved successfully.
failure GET requests
Other requests
Not applicable.
Some or all incoming items have caused processing errors. No items have been saved.
error All requests The request has not been processed due to a fatal error.

Response Structure

If the request has been processed successfully, or – in case of non-GET requests – if all items from the request body have been processed successfully, then the response object will contain a collection of processed items. It will also include a metadata object (described below).

If some or all items from the request body have caused processing errors, then the response body will contain a failures collection with invalid items (described below).

If the request has not been processed due to a fatal error, then the response object will contain an error item (described below).

Metadata Object

The metadata object describes the response and may include various properties, depending on the request and response parameters.

Property Data Type Presence Description
page Integer In response to GET requests Current page number.
pagesCount Integer In response to GET requests Total number of pages.
recordsPerPage Integer In response to GET requests Maximum number of records per each page.
recordsCount Integer In response to GET request Total number of records available.
receivedItemsCount Integer In response to POST, PATCH, and DELETE requests Total number of items received.
validItems List In response to POST, PATCH, and DELETE requests List of indices of valid items found in the request collection (if any).
invalidItems List In response to POST, PATCH, and DELETE requests List of indices of invalid items found in the request collection (if any).

Failures Collection

A failures collection contains items that cannot be processed correctly. These items can be mapped to the corresponding items from the original request collection by using indices from the invalidItems list of the response metadata object.

Property Data Type Presence Description
rawData Object Always present Raw item data as the API understands it.
errors Collection Always present An array of error objects.

Error Object

An error object contains detailed information about the error and may also contain some hints for developers describing how the error can be avoided.

Property Data Type Presence Description
type String Always present One of the following types: system, client, syntax, content, permission, validation.
code Integer Always present Error code.
message String Always present Error message.
description String May be present Verbose error description for developers (if available).
field String May be present in validation errors Name of the field whose value caused validation to fail.

Release Notes

Version 1.3

This version includes changes to timestamp formats, and an increase in API performance under certain circumstances.

All timestamps are now required to define microseconds.

New format:

2022-05-24T04:41:23.000000+00:00

Old Format:

2022-05-24T04:41:23+00:00

Terms of Service

Thank you for using GeoOp's APIs. These APIs are provided by GeoOp Ltd. (referred to as GeoOp we, our, or usin these terms), located at Level 3, 12 Heather Street, Parnell, Auckland, 1052 , New Zealand.

These terms outline your rights and responsibilities when using our APIs, so read them carefully. Additional terms may apply to the use of an API, including additional terms of service, terms within the accompanying API documentation, and any applicable policies or guidelines. If there is a conflict between these terms and the additional terms, the additional terms apply for that conflict. If you use the APIs as an interface to, or in conjunction with other GeoOp products and services, then the terms for such products and services also apply.


Section 1: Account and Registration

Accepting the Terms You may not use the APIs and may not accept the Terms if (a) you are not of legal age to form a binding contract with GeoOp, or (b) you are a person barred from using or receiving the APIs under the applicable laws of New Zealand or other countries including the country in which you are resident or from which you use the APIs.

Your GeoOp Account

You may need to create a GeoOp account in order to use an API or a GeoOp account may be assigned to you by an administrator, such as your employer or educational institution. If you are using a GeoOp account assigned to you by an administrator, your legal relationship with your administrator may affect that account. It's your responsibility to keep your password, account credentials, and accounts secure. If you learn of any unauthorized use of your account, follow the instructions at http://help.geoop.com/home

Registration

In order to access certain APIs you may be required to provide certain information (such as identification or contact details) as part of the registration process for the APIs, or as part of your continued use of the APIs. You agree that any registration information you give to GeoOp will always be accurate and up to date.

Subsidiaries and Affiliates

GeoOp has subsidiaries and affiliated legal entities around the world. You agree that these companies may provide the APIs to you on behalf of GeoOp and these terms will also govern your relationship with these companies.


Section 2: Using Our APIs

Your End Users

You will require your end users to comply with any applicable law and these terms. You will not knowingly enable your end users to violate applicable law or these terms.

Compliance with Law

You will use our APIs only as permitted by law (including without limitation laws regarding the import or export of data or software, privacy, or local laws). You will not use the APIs to encourage or promote illegal activity.

Permitted Access

You will only access (or attempt to access) an API by the means described in the documentation of that API. If GeoOp assigns you developer credentials or Client IDs, you must use them with the applicable APIs. You will not misrepresent or mask either your identity or your API Client's identity when using the APIs or developer accounts.

API Limitations

GeoOp may set limits on the number of API requests that you can make, at its sole discretion. You agree to such limitations and will not attempt to circumvent such limitations.

Open Source Software

Some of the software required by or included in our APIs may be offered under an open source license. There may be provisions in the open source license that expressly override some of these terms, and in those cases, the overriding provisions apply.

Monitoring

GeoOp may monitor the use of the APIs to ensure quality, improve GeoOp products and services, and verify your compliance with these terms. You will not interfere with such monitoring. GeoOp may use any technical means to overcome such interference.

Communication with GeoOp

You agree that we may send you certain communications in connection with your use of the APIs. Please review the applicable API documentation for information about opting out of certain types of communication.

Feedback

If you provide feedback or suggestions about our APIs, then we may use such information without obligation to you.


Section 3: Your API Clients

API Clients

The APIs are designed to help you enhance your websites and applications (API Client(s)). GeoOp reserves the right to investigate any API Client for compliance with these terms. Such investigations may include GeoOp accessing and using your API Client, for example to identify security issues that could affect GeoOp or its users. You consent to any such investigation. GeoOp may suspend access to our APIs by you or your API Client without notice if we reasonably believe that you are in violation of these terms.

Security

You will use commercially reasonable efforts to protect user information collected by your API Client, including personally identifiable information PII), from unauthorized access or use and will promptly report to your users any unauthorized access or use of such information.

Ownership

GeoOp does not acquire ownership in your API Clients, and by using our APIs, you do not acquire ownership of any rights in our APIs or the content that is accessed through our APIs.

User Privacy and API Clients

You will comply with all privacy laws and regulations including those applying to PII. You will provide and adhere to a privacy policy for your API Client that clearly and accurately describes to users of your API Client what user information you collect (such as PII, login information and GeoOp account data) and how you use and share such information (including for advertising) with GeoOp and third parties.


Section 4: Prohibitions

API Prohibitions

When using the APIs, the following prohibitions apply:

  • You will not sublicense an API for use by a third party. Consequently, you will not create an API Client that functions substantially the same as the APIs and offer it for use by third parties.
  • You will not perform an action with the intent of introducing to GeoOp products and services any viruses, worms, defects, Trojan horses, malware or any items of a destructive nature.
  • You will not defame, abuse, harass, stalk or threaten others.
  • You will not interfere with or disrupt the APIs or the servers or networks providing the APIs.
  • You will not promote or facilitate unlawful online gambling or disruptive commercial messages or advertisements.
  • You will not reverse engineer or attempt to extract the source code from any API or any related software, except to the extent that this restriction is expressly prohibited by applicable law.
  • Certain developer credentials are, by their nature, considered confidential. You will not disclose such confidential credentials to any third party except your agent(s) using such information solely on your behalf in accordance with these terms and under a written duty of confidentiality.
  • Our communications to you may contain GeoOp confidential information. If you receive any materials or communications that are clearly confidential or marked confidential, then you will not disclose the GeoOp confidential information to any third party without GeoOp's prior written consent.

Section 5: Content

Content Accessible Through our APIs

Our APIs contain some third party content (such as text, images, videos, audio, or software). This content is the sole responsibility of the person that makes it available. We may sometimes review content to determine whether it is illegal or violates our policies, and we may remove or refuse to display content. Finally, content accessible through our APIs may be subject to intellectual property rights, and, if so, you may not use it unless you are licensed to do so by the owner of that content or are otherwise permitted by law. Your access to the content provided by the API may be restricted, limited, or filtered in accordance with local laws, regulations, and policies.

Submission of Content

Some of our APIs allow the submission of content, and except as expressly provided in these terms, GeoOp does not acquire any ownership of any intellectual property rights that you or your end users hold in the content that you submit to our APIs through your API Client. By submitting, posting or displaying content to or from the APIs through your API Client, you give GeoOp a perpetual, irrevocable, worldwide, royalty-free, and non-exclusive license to reproduce, adapt, modify, translate, publish, publicly perform, publicly display and distribute such content. However, GeoOp will only use such content for the purpose of enabling GeoOp to provide the APIs and only in accordance with the applicable GeoOp privacy policies. You agree that this license includes a right for GeoOp to make such content available to other companies, organizations or individuals with whom GeoOp has relationships for the provision of syndicated services, and to use such content in connection with the provision of those services. Before you submit content to our APIs through your API Client, ensure that you have the necessary rights (including the necessary rights from your end users) to grant us the license.

Retrieval of content

When a user's non-public content is obtained through the APIs, you may not expose that content to other users or to third parties without explicit opt-in consent from that user.

Data Portability

GeoOp supports data portability. By accessing users' data through the APIs for use in any of your services or applications, you agree to enable your users of any such service or application to export their equivalent data to other services or applications of their choice in a way that's substantially as fast and easy as exporting such data from GeoOp products and services, subject to applicable laws.

Prohibitions on Content

Unless expressly permitted by the content owner or by applicable law, you agree that you will not, and will not permit your end users to, do the following with content returned from the APIs:

  • Scrape, build databases or otherwise create permanent copies of such content, or keep cached copies longer than permitted by the cache header;
  • Copy, translate, modify, create a derivative work of, sell, lease, lend, convey, distribute, publicly display or sublicense to any third party;
  • Misrepresent the source or ownership; or
  • Remove, obscure, or alter any copyright, trademark or other proprietary rights notices, falsify or delete any author attributions, legal notices or other labels of the origin or source of material.

Section 6: Brand Features; Attribution

"Brand Features" is defined as the trade names, trademarks, service marks, logos, domain names, and other distinctive brand features of each party. Except where expressly stated, these terms do not grant either party any right, title, or interest in or to the other party's Brand Features. All use by you of GeoOp's Brand Features (including any goodwill associated therewith) will inure to the benefit of GeoOp.

Attribution

You agree to display any attribution(s) required by GeoOp as described in the documentation for the API. GeoOp hereby grants to you a non-transferable, non-sublicenseable, non-exclusive license during the term to display GeoOp's Brand Features for the purpose of promoting or advertising that you use the APIs. You must only use the GeoOp Brand Features in accordance with these terms and for the purpose of fulfilling your obligations under this Section. You understand and agree that GeoOp has the sole discretion to determine whether your attribution(s) and use of GeoOp's Brand Features are in accordance with the above requirements.

Publicity

You will not make any statement regarding your use of an API which suggests partnership with, sponsorship by or endorsement by without GeoOp's prior written approval.

Promotional and Marketing Use

In the course of promoting, marketing, or demonstrating the APIs you are using and the associated GeoOp products, GeoOp may produce and distribute incidental depictions, including screenshots, video, or other content from your API Client, and may use your company or product name. You grant us all necessary rights for the above purposes.


GeoOp Privacy Policies

By using our APIs, you agree that GeoOp can use submitted information in accordance with our privacy policies, such as http://www.geoop.com/terms-and-conditions


Section 8: Termination

Termination

You may stop using our APIs at any time. If you want to terminate these terms, you must provide GeoOp with 7 days prior written notice and upon termination, cease your use of the applicable APIs. GeoOp reserves the right to terminate these terms or discontinue the APIs or any portion or feature for any reason and at any time without liability or other obligation to you.

Your Obligations Post-Termination

Upon any termination of these terms or discontinuation of your access to an API, you will immediately stop using the API, cease all use of the GeoOp Brand Features, and delete any cached or stored content that was permitted by the cache header under Section 5. GeoOp may independently communicate with any account owner whose account(s) are associated with your API Client and developer credentials to provide notice of the termination of your right to use an API.

Surviving Provisions

When these terms come to an end, those terms that by their nature are intended to continue indefinitely will continue to apply, including but not limited to: Sections 8, 9, and 10.


Section 9: Liability for our APIs

WARRANTIES

NEITHER GEOOP NOR ITS SUPPLIERS OR DISTRIBUTORS MAKE ANY SPECIFIC PROMISES ABOUT THE APIS. FOR EXAMPLE, WE DON'T MAKE ANY COMMITMENTS ABOUT THE QUALITY OF THE APIS OR THE CONTENT ACCESSED THROUGH THE APIS, THEIR RELIABILITY, AVAILABILITY OR ABILITY TO MEET YOUR NEEDS. THE APIS AND CONTENT ACCESSED THROUGH THE APIS ARE PROVIDED "AS IS". SOME JURISDICTIONS PROVIDE FOR CERTAIN WARRANTIES, LIKE THE IMPLIED WARRANTY OF THE MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. TO THE EXTENT PERMITTED BY LAW, WE EXCLUDE ALL IMPLIED WARRANTIES.

LIMITATION OF LIABILITY

WHEN PERMITTED BY LAW, GEOOP, AND GEOOP'S SUPPLIERS AND DISTRIBUTORS, WILL NOT BE RESPONSIBLE FOR LOST PROFITS, REVENUES, OR DATA, FINANCIAL LOSSES OR INDIRECT, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES. TO THE EXTENT PERMITTED BY LAW, THE TOTAL LIABILITY OF GEOOP, AND ITS SUPPLIERS AND DISTRIBUTORS, FOR ANY CLAIM UNDER THESE TERMS, INCLUDING FOR ANY WARRANTIES THAT MAY NOT LEGALLY BE EXCLUDED, IS LIMITED TO THE AMOUNT YOU PAID US TO USE THE APIS (OR, IF WE CHOOSE, TO SUPPLYING YOU THE APIS AGAIN) DURING THE SIX MONTHS PRIOR TO THE EVENT GIVING RISE TO THE LIABILITY. NOTHING IN THESE TERMS LIMITS YOUR RESPONSIBILITY FOR INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS. IN ALL CASES, GEOOP, AND ITS SUPPLIERS AND DISTRIBUTORS, WILL NOT BE LIABLE FOR ANY LOSS OR DAMAGE THAT IS NOT REASONABLY FORESEEABLE.

Indemnification

You agree to hold harmless and indemnify GeoOp, and its subsidiaries, affiliates, officers, agents, and employees, or partners, from and against any third party claim arising from or in any way related to:

  • your misuse or your end user's misuse of the APIs; or
  • your violation or your end user's violation of these terms, including any liability or expense arising from all claims, losses, damages (actual and consequential), suits, judgments, litigation costs and attorneys' fees, of every kind and nature. In such a case, GeoOp will provide you with written notice of such claim, suit or action.

Section 10: General Provisions

Modification

We may modify these terms or any additional terms that apply to an API occasionally, for example, to reflect changes to the law or changes to our APIs. We'll post notice of modifications to these terms or the additional terms within the documentation of each applicable API. Changes are effective seven (7) days after they are posted. However, changes specific to new functionality for an API or changes made for legal reasons will be effective immediately. You agree that your continued use of the API constitutes an acceptance of the modified terms.

These terms control the relationship between GeoOp and you. They do not create any third party beneficiary rights. If you do not comply with these terms, and GeoOp does not take action right away, this does not mean that GeoOp is giving up any rights that it may have (such as taking action in the future). If it turns out that a particular term is not enforceable, this will not affect any other terms. The laws of New Zealand will apply to any disputes arising out of or related to these terms or the services. ALL CLAIMS ARISING OUT OF OR RELATING TO THESE TERMS OR THE SERVICES WILL BE LITIGATED EXCLUSIVELY IN THE COURTS OF AUCKLAND, NEW ZEALAND, AND YOU AND GEOOP CONSENT TO PERSONAL JURISDICTION IN THOSE COURTS.

accounts

accounts

Fetch Account

Fetch all Account that match optional filters and sorting

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "accounts": [
    ]
}

clients

clients

Fetch Clients

Fetch all Clients that match optional filters and sorting

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[] - Hydrate all fields and associations

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "clients": [
    ]
}

Create Clients

Create 1 or more Clients for the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Client)

Responses

Request samples

Content type
application/json
{
  • "clients": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "clients": [
    ]
}

Edit Clients

Edit 1 or more Clients in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Client)

Responses

Request samples

Content type
application/json
{
  • "clients": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "clients": [
    ]
}

Edit Client

Edit a single Client in the current Account

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>
Request Body schema: application/json
Array of objects (Client)

Responses

Request samples

Content type
application/json
{
  • "clients": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "clients": [
    ]
}

files

files

Fetch Files

Fetch all Files that match optional filters and sorting

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[] - Hydrate all fields and associations

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "files": [
    ]
}

Edit Files

Edit 1 or more Files in the current Account

Authorizations:
OAuth2

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "files": [
    ]
}

File Upload

You can upload binary data by sending a POST request to the /files/upload action endpoint. Put binary data into the request body and specify the MIME type of the file in the Content-Type header. The name of the file can be specified in the Content-Disposition header (otherwise it will be generated by the API Server).

Authorizations:
OAuth2
Request Body schema: application/octet-stream
string <binary>

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "files": [
    ]
}

Delete a File

Delete a single File in the current Account

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "files": [
    ]
}

Edit File

Edit a single File in the current Account

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "files": [
    ]
}

invoices

invoices

Create Invoices

Create 1 or more Invoices in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (CreateInvoiceRequest)

Responses

Request samples

Content type
application/json
{
  • "invoices": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "invoices": [
    ]
}

Delete Invoice

Delete 1 or more Invoices in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (EntityId)

Responses

Request samples

Content type
application/json
{
  • "invoices": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "invoices": [
    ]
}

Edit Invoice

Edit 1 or more Invoices in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Invoice)

Responses

Request samples

Content type
application/json
{
  • "invoices": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "invoices": [
    ]
}

Send Invoices

Send an Invoice Message via email or sms

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>
Request Body schema: application/json
Array of objects (MessageRequest)

Responses

Request samples

Content type
application/json
{
  • "messages": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "invoices": [
    ]
}

jobs

jobs

Fetch Jobs

Fetch all Jobs that match optional filters and sorting

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[] - Hydrate all fields and associations

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

accept-associations
string
Examples:
  • accept-associations=?accept-Associations=all - Will return both active and deleted associations that have been requested in the `fields` parameter. This is the default behaviour if header is not specified
  • accept-associations=accept-associations=active - Will return only active associations that have been requested in the `fields` parameter

Associations to accept if requested in fields. Accepted values are all or active.

header Parameters
Accept-Associations
string
Examples:
  • Accept-Associations: all - Will return both active and deleted associations that have been requested in the `fields` parameter. This is the default behaviour if header is not specified
  • Accept-Associations: active - Will return only active associations that have been requested in the `fields` parameter

Associations to accept if requested in fields. Accepted values are all or active.

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "jobs": [
    ]
}

Create Jobs

Create 1 or more Jobs for the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Job)

Responses

Request samples

Content type
application/json
{
  • "jobs": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "jobs": [
    ]
}

Edit Job

Edit 1 or more Jobs in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Job)

Responses

Request samples

Content type
application/json
{
  • "jobs": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "jobs": [
    ]
}

Edit Job

Edit a single Job in the current Account

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>
Request Body schema: application/json
Array of objects (Job)

Responses

Request samples

Content type
application/json
{
  • "jobs": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "jobs": [
    ]
}

jobs/charges

jobs/charges

Fetch all Job Charges

Fetch all Job Charges that match optional filters and sorting

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[*] - Hydrate all Charge fields and associations
  • fields=*,user[*],job[*] - Hydrate all Charge fields including user and job associations
  • fields=*,user[id, firstName, lastName] - Hydrate all fields and the user association with only id, firstName and lastName hydrated
  • fields=id,time,unitPrice,quantity,user[id, firstName, lastName] - Hydrate id, time, unitPrice and quantity including the user association with only id, firstName and lastName hydrated

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "charges": [
    ]
}

Fetch a Job Charge by ID

Fetch one Job Charge using its unique ID

Authorizations:
OAuth2
query Parameters
fields
string
Examples:
  • fields=*,[*] - Hydrate all Charge fields and associations
  • fields=*,user[*],job[*] - Hydrate all Charge fields including user and job associations
  • fields=*,user[id, firstName, lastName] - Hydrate all fields and the user association with only id, firstName and lastName hydrated
  • fields=id,time,unitPrice,quantity,user[id, firstName, lastName] - Hydrate id, time, unitPrice and quantity including the user association with only id, firstName and lastName hydrated

Specify fields/associations to hydrate in response

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "charges": [
    ]
}

Fetch all Job Charges for a specific Job

Fetch all Job Charges that match optional filters and sorting

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[*] - Hydrate all Charge fields and associations
  • fields=*,user[*],job[*] - Hydrate all Charge fields including user and job associations
  • fields=*,user[id, firstName, lastName] - Hydrate all fields and the user association with only id, firstName and lastName hydrated
  • fields=id,time,unitPrice,quantity,user[id, firstName, lastName] - Hydrate id, time, unitPrice and quantity including the user association with only id, firstName and lastName hydrated

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "charges": [
    ]
}

customFields

customFields

Fetch CustomFields

Fetch all CustomFields that match optional filters and sorting

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[] - Hydrate all fields and associations

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "customFields": [
    ]
}

Create CustomFields

Create 1 or more CustomFields for the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (CustomField)

Responses

Request samples

Content type
application/json
{
  • "customFields": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "customFields": [
    ]
}

Edit CustomField

Edit 1 or more CustomFields in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (CustomField)

Responses

Request samples

Content type
application/json
{
  • "customFields": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "customFields": [
    ]
}

Edit CustomField

Edit a single CustomField in the current Account

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>
Request Body schema: application/json
Array of objects (CustomField)

Responses

Request samples

Content type
application/json
{
  • "customFields": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "customFields": [
    ]
}

notes

notes

Fetch Notes

Fetch all Notes that match optional filters and sorting

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[] - Hydrate all fields and associations

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "notes": [
    ]
}

Create Notes

Create 1 or more Notes for the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Note)

Responses

Request samples

Content type
application/json
{
  • "notes": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "notes": [
    ]
}

Edit Note

Edit 1 or more Notes in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Note)

Responses

Request samples

Content type
application/json
{
  • "notes": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "notes": [
    ]
}

Edit Note

Edit a single Note in the current Account

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>
Request Body schema: application/json
Array of objects (Note)

Responses

Request samples

Content type
application/json
{
  • "notes": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "notes": [
    ]
}

statuses

statuses

Fetch Statuses

Fetch all Statuses that match optional filters and sorting

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[] - Hydrate all fields and associations

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "statuses": [
    ]
}

Create Statuses

Create 1 or more Statuses for the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (JobStatus)

Responses

Request samples

Content type
application/json
{
  • "statuses": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "statuses": [
    ]
}

Edit Statuses

Edit 1 or more Statuses in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (JobStatus)

Responses

Request samples

Content type
application/json
{
  • "statuses": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "statuses": [
    ]
}

Edit Status

Edit a single Status in the current Account

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>
Request Body schema: application/json
Array of objects (JobStatus)

Responses

Request samples

Content type
application/json
{
  • "statuses": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "statuses": [
    ]
}

visits

visits

Fetch Visits

Fetch all Visits that match optional filters and sorting. Results are limited to 65,535 jobs per account (regardless of the size page).

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[] - Hydrate all fields and associations

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "visits": [
    ]
}

Create Visits

Create 1 or more Visits for the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Visit)

Responses

Request samples

Content type
application/json
{
  • "visits": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "visits": [
    ]
}

Edit Visit

Edit 1 or more Visits in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Visit)

Responses

Request samples

Content type
application/json
{
  • "visits": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "visits": [
    ]
}

Edit Visit

Edit a single Visit in the current Account

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>
Request Body schema: application/json
Array of objects (Visit)

Responses

Request samples

Content type
application/json
{
  • "visits": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "visits": [
    ]
}

messages

messages

Send Messages

Send a Message via email or sms

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (MessageRequest)

Responses

Request samples

Content type
application/json
{
  • "messages": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "messages": [
    ]
}

users

users

Fetch Users

Fetch all Users that match optional filters and sorting

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[] - Hydrate all fields and associations

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "users": [
    ]
}

Create Users

Create 1 or more Users for the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (User)

Responses

Request samples

Content type
application/json
{
  • "users": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "users": [
    ]
}

Edit Users

Edit 1 or more Users in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (User)

Responses

Request samples

Content type
application/json
{
  • "users": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "users": [
    ]
}

Edit User

Edit a single User in the current Account

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>
Request Body schema: application/json
Array of objects (User)

Responses

Request samples

Content type
application/json
{
  • "users": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "users": [
    ]
}

workgroups

workgroups

Fetch Workgroups

Fetch all Workgroups that match optional filters and sorting

Authorizations:
OAuth2
query Parameters
where
string
Examples:
  • where=job = 1 - filter job by id
  • where=job in (123,234,23) - filter job by multiple IDs

Where clause to filter response

fields
string
Examples:
  • fields=*,[] - Hydrate all fields and associations

Specify fields/associations to hydrate in response

sort
string
Examples:
  • sort=firstName - sort by firstName

Sorting the requested collection by specified fields and/or associations

page
string
Examples:
  • page=3,25 - Return page 3 with 25 items per page

enable pagination of requested collection

Responses

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "workgroups": [
    ]
}

Create Workgroups

Create 1 or more Workgroups for the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Workgroup)

Responses

Request samples

Content type
application/json
{
  • "workgroups": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "workgroups": [
    ]
}

Edit Workgroup

Edit 1 or more Workgroups in the current Account

Authorizations:
OAuth2
Request Body schema: application/json
Array of objects (Workgroup)

Responses

Request samples

Content type
application/json
{
  • "workgroups": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "workgroups": [
    ]
}

Edit Workgroup

Edit a single Workgroup in the current Account

Authorizations:
OAuth2
path Parameters
id
required
integer <int64>
Request Body schema: application/json
Array of objects (Workgroup)

Responses

Request samples

Content type
application/json
{
  • "workgroups": [
    ]
}

Response samples

Content type
application/json
{
  • "result": "string",
  • "metadata": {
    },
  • "workgroups": [
    ]
}