Get started with the Web API

Introduction

This document describes Web API exposed through Bentley Web Services Gateway. All API is based on standard HTTP methods to enable cross platform and language support. Bentley Web Services Gateway Web API is dynamic by design. This document describes the rules of building URLs and requests; exact URLs can vary for different domains. Exchangeable parts are clearly marked in the document and enclosed in braces {}. The exchangeable parts include:

  • ID of repositories deployed in a specific environment
  • Names of classes, properties, and relationships exposed from different types of repositories

All these items can be queried in runtime using standard Web API calls. Please refer to the Quick start guide and API reference for more information.

Depending on the request, the response format can be either JSON or binary. Please refer to the API reference for exact format definition.

All the examples in this document presume that Bentley Web Services Gateway is deployed and accessible using URL "https://localhost/ws". Please replace the server and/or application name to match your exact deployment.

For a trial of API, please visit the API Explorer tool delivered with each Bentley Web Services deployment, found at https://localhost/ws.


HTTP Request headers

With each HTTP request to Bentley Web Services Gateway Web API, appropriate headers should be provided for all HTTP methods (GET, POST, PUT, DELETE).

Required headers

  • All requests having a {RepositoryId} parameter must have one of the following:
    • Basic Authorization header. For example:
      Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
      The Basic parameter is a base-64 encoded string "username:password".
    • Token header with a token that is understood by the plugin. Currently supported token versions are Bentley STS and OAuth2.

Note: For Bentley Web Services Gateway running in the Bentley CONNECT environment, all requests must have a Token header. On-premise installation allows a request to list Repositories without authorization headers.

  • Mas-App-Guid - unique GUID generated per client application installation.
  • Mas-Uuid - unique GUID generated for the device running client application.
  • User-Agent - used for determining compatibility between application and server, and should be provided in the following format: <applicationName>/<version>.

Optional headers

  • Accept-Language - used for localization purposes.
  • Mas-Allow-File-Compression (from API 2.3) - If HTTP header "Mas-Allow-File-Compression: True" is present and IIS is configured to allow dynamic compression, files are downloaded compressed (with gzip or other tool).

    Note: If dynamic compression is used, "Content-Length" header is not returned and the file is sent using chunked transfer encoding.
    Note 2: If a resumable file download is used, the Range header specifies the bytes range in an uncompressed file.

  • Mas-Request-Id (from API 2.7) - If this header value is a valid GUID, it will be set in HTTP response header 'Mas-Request-Id', otherwise a new value will be generated and used for request tracking in logs.

Responses and Errors

All successful requests return one of the following HTTP status codes:

  • 200 (OK) - a resource was successfully retrieved/modified/deleted.
  • 201 (Created) - a resource was successfully created.
  • 304 (Not Modified) - a resource was not modified. Responses from some APIs (for example, getting files or object instances) contain an ETag header and ETag value in JSON, which can then be used for the next request for the same resource in an If-None-Match header. If the If-None-Match header is used and the resource has not changed on the server, then the response body will be empty and status code will be 304. Otherwise, the response body will have a requested resource and the status code will be 200.

If an error occurs while processing the request, one of the following HTTP status codes is returned:

  • 400 (Bad Request) - the parameters in the request URL or request body are not valid for a resource.
  • 401 (Unauthorized) - the Authorization header is missing or invalid, or the username or password is incorrect for the requested repository.
  • 403 (Forbidden) - the client is not permitted to access the resource.
  • 404 (Not Found) - something (the resource URL, repository, class, object, file, etc.) was not found.
  • 409 (Conflict) - the request conflicts with an existing resource. This would most likely occur when creating new objects (for example, an object with the same name that already exists in the same context).
  • 500 (Internal Server Error) - something unexpected occurred.
  • 501 (Not Implemented) - the requested API or some parameters are not supported.
  • 503 (Service Unavailable) - the server is not available or may not be licensed, or the client does not have a license.

The status codes specific for some Web API can be found with a description of specific Web API calls.

When an error occurs at the API level, the response will adhere to the following JSON format:

{
    "errorId": "An id",
    "errorMessage": "A message.",
    "errorDescription": "A description."
}

The errorId can be one of the following general error ids:

  • LoginFailed
  • SslRequired
  • NotEnoughRights
  • RepositoryNotFound (replaces API 1.3 DatasourceNotFound)
  • SchemaNotFound
  • ClassNotFound
  • PropertyNotFound
  • InstanceNotFound (replaces API 1.3 ObjectNotFound)
  • FileNotFound
  • NotSupported
  • NoServerLicense
  • NoClientLicense
  • TooManyBadLoginAttempts

Deprecated error ids:

  • LinkTypeNotFound
  • DatasourceNotFound (replaced by RepositoryNotFound)
  • ObjectNotFound (replaced by InstanceNotFound)

Server and Web API version

HTML pages (on premise)

On-premise deployment Bentley Web Services Gateway exposes the following static pages:

https://localhost/ws - landing page to test your deployment

https://localhost/ws/Pages/About.aspx - server and API versions

Response headers

The Bentley Web Services Gateway product version and Web API version can be found in the standard Server header and custom Mas-Server header (for servers from 2.6.2 and up) of each response:

  • Bentley-WSG : 4-number version of Web Services Gateway product
  • Bentley-WebAPI : 2-number Web API version

Versions are duplicated because some proxy servers can override the standard Server header so it is better to check with the custom one.

For example:

Server: Bentley-WSG/02.06.02.02
Server: Bentley-WebAPI/2.6
Mas-Server: Bentley-WSG/02.06.02.02
Mas-Server: Bentley-WebAPI/2.6

Please refer to the API reference for exposing additional plugin version value.


Quick start guide

This section provides examples of a few basic requests. The most used Web API calls will need the following information included in the URL:

  • Repository ID
  • Schema name (representing the service inside the repository)
  • Class name of the domain object

All this information can be queried at runtime. The first few examples illustrate how to examine metadata for the server by retrieving the server version, available repositories, services (schemas) in a selected repository, and domain object classes in a selected schema. The second portion of examples focuses on the Persistence service, and illustrates how to query specific object instances and how to download the file attached to that object. Please refer to the API reference for the full API documentation.

Checking for the server version

The server version can be found:

Retrieving list of repositories

A list of configured repositories can be retrieved using GET https://localhost/ws/v2.5/Repositories request. The response will contain a list of RepositoryIdentifier class instances, each describing a specific repository. The ID of the repository (value of instanceId field in the response) is a mandatory parameter for all further Web API calls accessing the exact repository (further referred as {repositoryId}). The example below shows two repositories with following IDs:

  • eB--MyWarehouse
  • PW--PW
{
 "instances": [
  {
  "instanceId": "Bentley.eB--MyWarehouse",
  "className": "RepositoryIdentifier",
  "schemaName": "Repositories",
  "eTag": "uBXbj6nWff66M53yGm59yn72WIQ=",
  "properties": {
       "ECPluginID": "Bentley.eB",
       "Location": "myserver: MyWarehouse",
       "DisplayLabel": "myserver:wpd",
       "Description": " myserver:wpd"
       }
  },
  {
   "instanceId": "Bentley.PW--PW",
   "className": "RepositoryIdentifier",
   "schemaName": "Repositories",
   "eTag": "hTrWRZL9mbqK0JhXE4UcScHBTLs=",
   "properties": {
        "ECPluginID": "pw",
        "Location": " myserver:pw",
        "DisplayLabel": "myserver:pw",
        "Description": "myserver:pw"
        }
  }
 ]
}

Retrieving list of schemas in selected repository

Each repository can expose services described by the schema. A Schema describes types of resources (objects) exposed by a specific service. For example:

  • Navigation service exposes NavNode objects for exposing object hierarchy in the repository.
  • Views service exposes View and ContentGroup objects for exposing custom views in the repository, if any.
  • MetaSchema schema service exposes ECSchemaDef, ECClassDef and ECPropertyDef objects to be used in describing the services themselves.
  • Persistence service exposes all domain objects available in the repository. This is the most used service while querying or manipulating the domain objects. Persistence service can be accessed using the names of schemas exposed by a repository – it is common for repositories to expose more than one schema to group and separate domain objects (see example below).

A list of all schemas in the repository can be retrieved using request

GET https://localhost/ws/v2.5/Repositories/{repositoryId}/MetaSchema/ECSchemaDef

Where {repositoryId} should be replaced with the repository ID from the previous request. For example:

GET https://localhost/ws/v2.5/Repositories/Bentley.PW--PW/MetaSchema/ECSchemaDef

Besides persistence schemas, this request will return a set of standard service schemas (Policies, Views, Contents, Navigation, MetaSchema) and helper schemas (Bentley_Standard_Classes, DataSourceSpecification, EditorCustomAttributes, Bentley_Standard_CustomAttributes).

The response (see excerpt from the sample response below) will contain a list of schema definition instances, each describing an available schema in the repository. The highlighted schema names can be used in further requests to manipulate domain objects.

{
 "instances": [
    {
      "instanceId": "N~3APW_WSG_Dynamic.01.00",
      "className": "ECSchemaDef",
      "schemaName": "MetaSchema",
      "eTag": "Afe0hcjEZXEHM/4L2+OPLkmexMk=",
      "properties": {
        "Name": "PW_WSG_Dynamic",
        "DisplayLabel": "ProjectWise Web Services Gateway Dynamic Schema",
        "NameSpacePrefix": "pwwsg",
        "Description": "Schema used for ProjectWise plugin for Bentley Web Services Gateway",
        "VersionMajor": 1,
        "VersionMinor": 0
      }
    },
    {
      "instanceId": "N~3APW_WSG.02.00",
      "className": "ECSchemaDef",
      "schemaName": "MetaSchema",
      "eTag": "aZcDzPMmpRff5NYAnS+9NXhNqNM=",
      "properties": {
        "Name": "PW_WSG",
        "DisplayLabel": "ProjectWise Web Services Gateway Schema",
        "NameSpacePrefix": "pwwsg",
        "Description": "Schema used for ProjectWise plugin for Bentley Web Services Gateway",
        "VersionMajor": 2,
        "VersionMinor": 0
      }
    },
    {
      "instanceId": "N~3ABentley_Standard_CustomAttributes.01.10",
      "className": "ECSchemaDef",
      "schemaName": "MetaSchema",
      "eTag": "QnwLoYXpOHVvhAzqjGsaOujM5Eg=",
      "properties": {
        "Name": "Bentley_Standard_CustomAttributes",
        "DisplayLabel": "Bentley Standard Custom Attributes",
        "NameSpacePrefix": "bsca",
        "Description": "Bentley Standard Custom Attributes",
        "VersionMajor": 1,
        "VersionMinor": 10
      }
    },
 ]
}

Retrieving list of classes from the schema

If unknown in advance, it is possible to query for classes in a specified schema using the request:

GET https://localhost/ws/v2.5/Repositories/{repositoryId}/MetaSchema/ECClassDef?$filter=SchemaHasClass-backward-ECSchemaDef.Name+in+['{schemaName}']

Where {repositoryId} and {schemaName} should be replaced with information from previous requests. For example:

GET https://localhost/ws/v2.5/Repositories/Bentley.PW--PW/MetaSchema/ECClassDef?$filter=SchemaHasClass-backward-ECSchemaDef.Name+in+['PW_WSG']

The response (see excerpt from the sample response below) will contain a list of class definition instances describing each available class in the schema. The highlighted class names can be used in further requests to manipulate domain objects.

{
  "instances": [
    {
      "instanceId": "N~3APW_WSG.02.00~3ADocument",
      "className": "ECClassDef",
      "schemaName": "MetaSchema",
      "eTag": "sB+Eu/8RepfCwBGXyGvdisq1Iuw=",
      "properties": {
        "Name": "Document",
        "DisplayLabel": "Document",
        "Schema": "PW_WSG.02.00",
        "Description": "Represents any ProjectWise document",
        "IsStruct": false,
        "IsCustomAttributeClass": false,
        "IsDomainClass": true,
        "HasBaseClasses": false,
        "IsRelationshipClass": false,
        "BaseClasses": [
        ]
      }
    },
    {
      "instanceId": "N~3APW_WSG.02.00~3AEnvironment",
      "className": "ECClassDef",
      "schemaName": "MetaSchema",
      "eTag": "ALcLACcO/8IK96lYRvh1FT7rXak=",
      "properties": {
        "Name": "Environment",
        "DisplayLabel": "Environment",
        "Schema": "PW_WSG.02.00",
        "Description": "Represents a ProjectWise document environment",
        "IsStruct": false,
        "IsCustomAttributeClass": false,
        "IsDomainClass": true,
        "HasBaseClasses": false,
        "IsRelationshipClass": false,
        "BaseClasses": [
          
        ]
      }
    },
    {
      "instanceId": "N~3APW_WSG.02.00~3AProject",
      "className": "ECClassDef",
      "schemaName": "MetaSchema",
      "eTag": "YT5KksnTzm5pXxtKapmabCvcu7I=",
      "properties": {
        "Name": "Project",
        "DisplayLabel": "Project",
        "Schema": "PW_WSG.02.00",
        "Description": "Represents any ProjectWise project or folder",
        "IsStruct": false,
        "IsCustomAttributeClass": false,
        "IsDomainClass": true,
        "HasBaseClasses": false,
        "IsRelationshipClass": false,
        "BaseClasses": [
          
        ]
      }
    },
  ]
}

Retrieving the object instances

There are multiple ways to retrieve class instances:

  • Retrieve a single instance by specifying the exact instance ID. Such URLs can be reused as persistent links to the object instance.
  • Retrieve multiple instances of one or more classes by specifying the query parameters in a URL. Bentley Web Services Gateway Web API supports an OData style query string. Please refer to the API reference for the full query syntax documentation.
  • As return information from a URL to modify or create a new instance.

To retrieve a single instance by the unique ID, use URL:

GET https://localhost/ws/v2.5/Repositories/{repositoryId}/{schema}/{class}/{instanceId}

For example:

GET https://localhost/ws/v2.5/Repositories/Bentley.PW--PW/PW_WSG/Document/e899a390-d4c1-4904-8147-4d281139e516

Omitting an instance ID will return all instances of specified class in the repository. It is possible to specify query criteria and apply filters to limit the amount of returned instances:

GET https://localhost/ws/v2.5/Repositories/{repositoryId}/{schema}/{class}?$filter={PropertyName}+eq+'{value}'

For example:

GET https://localhost/ws/v2.5/Repositories/Bentley.PW--PW/PW_WSG/Document?$filter=Name+eq+'MyName'

As all data from Web API is returned as instance data, the return JSON format is the same as shown in the examples below: each instance contains an ID, class name, schema name, eTag and properties that are defined in the class definition.

Downloading file attached to the object instance

Web API supports the attachment of one file to any class object. Internal logics of each repository define which domain objects can have files attached and limit the attachment of files to certain objects. For example, you can typically attach a file to Document instances, but not to Folder instances. In cases when Document can have multiple files, the File is modeled as a separate domain class. Document instances can have multiple related File instances, and each File instance can have one binary file attached.

To retrieve an instance's attached binary file, add /$file parameter to the instance URL:

GET https://localhost/ws/v2.5/Repositories/{repositoryId}/{schema}/{class}/{instanceId}/$file

For example, the following URL will start streaming the file to the client (which can be tested in any browser):

GET https://localhost/ws/v2.5/Repositories/Bentley.PW--PW/PW_WSG/Document/e899a390-d4c1-4904-8147-4d281139e516/$file


Copyright © 2018 Bentley Systems, Incorporated. All rights reserved.