1. Purpose

This guide aims to familiarise you with the use of the REST APIs offered by CARL Source, based on practical examples.

2. Overview

Most applications encapsulate calls to REST APIs in the language of your choice, but it is important to be familiar with the HTTP methods of the underlying API.
We will therefore use cURL to interact with the APIs.

2.1. Prerequisites

  1. The connection between your workstation and CARL Source must be encrypted: Indeed, sensitive information (password and protected data) will pass through the network during this tutorial.
    The URL used to access CARL Source must therefore start with https://.

Warning

For these secure exchanges, we recommend using TLS v1.3.
The server hosting the CARL Source solution must be configured accordingly.

Note that TLS versions 1.0 and 1.1 are prohibited.

 

  1. You must have a valid CARL Source username.

 

  1. Your password must also be valid (i.e. neither «expired» nor «to be changed»).
    To check, connect to the CARL Source application via the login page.

 

Important

Please note that URLs containing square brackets ([ and ]) must be encoded with these characters (%5B and %5D respectively), otherwise they will be rejected.
However, the brackets will be retained in the examples in this document for ease of reading.

 
 

2.2. Hello World

Let’s start by making sure that the cURL tool and the API are accessible.
Open a terminal window and enter the following command (adjust the values in red):

> curl https://carlsource.server.com/gmaoCS02/public/status
status: ok

The response is a single line of text status: ok, which confirms that CARL Source is properly installed and accessible via the URL entered.

3. Authentication

Authentication information must generally be transmitted in order to use the services.
If, when access to a protected service is requested, the username or password provided is invalid, the API returns an HTTP 401 error (Unauthorized):

> curl -X GET -i https://carlsource.server.com/gmaoCS02/api/entities/v1/mr

HTTP/1.1 401 Unauthorized
{
    "errors" : [ {
        "status" : "401",
        "title" : "Unauthorized",
        "detail" : "Please provide valid authentication credentials"
    } ]
}

Authentication is the key to reading and writing private information via the API.

3.1. Token Authentication

For application needs, sending the username and password information with every interaction with the API can seem cumbersome and increases the risk of password theft.

The best way to handle this situation is to request the application (in this case CARL Source) to generate an access token, then include it in subsequent requests.
This token replaces the direct use of the "username/password" pair and thus prevents exposing this sensitive information at every call.

CARL Source supports two mechanisms for obtaining an access token:

  • CARL Source Token (type (carlsource_auth_v1)): obtained through the service /api/auth/v1/authenticate and sent in the HTTP header X-CS-Access-Token.

  • OAuth2 Token (type (Bearer)): compliant with RFC 6750, obtained through the service /api/oauth2/v1/token and sent in the standard header Authorization: Bearer.

In both cases, the authentication service is called only once to obtain the access token. This token is then used to authenticate all subsequent requests, without needing to resend credentials or authentication information.

CARL Source Token Example
> curl -X POST -i --data "login=identifiant" --data "password=mot_de_passe" --data "origin=your_application_identifier" https://carlsource.server.com/gmaoCS02/api/auth/v1/authenticate

HTTP/1.1 200
{
    "X-CS-Access-Token":"your_access_token",
    "token_type":"carlsource_auth_v1",
    "expires_in":86399911,
    "lang":"fr_FR"
}
OAuth2 Token Example
> curl -X POST https://carlsource.server.com/gmaoCS02/api/oauth2/v1/token -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=password" -d "client_id=your_application_identifier"

HTTP/1.1 200
{
    "access_token": "your_access_token",
    "token_type": "Bearer",
    "expires_in": 3600
}
Note

The values of the origin and client_id attributes accept a maximum length of 33 characters.

The fragment of JSON obtained in return firstly includes the token, which consists of a random sequence of characters.
CARL Source checks the validity of the token, which should be placed in an http query header named X-CS-Access-Token.

The following information is also included in the header:

  • The token type : to date, there are two types of tokens in CARL Source (carlsource_auth_v1) and (bearer).
    It is possible that refresh tokens may be available in the future.

  • The lifetime of this token (in milliseconds).
    Once this time has elapsed, a query made using this token will be rejected.
    The lifetime is configurable in the CARL Source system configuration settings.

  • The language of the user who requested the token.
    This information allows the requesting application to switch to the user’s preferred language as soon as possible (for example, if the user has logged in from a browser configured in a language other than their own).
    Note that the language of reference is the one defined for the CARL Source user.

Note

The language is returned only in the case of a (carlsource_auth_v1) token.

Once the token has been obtained, it can be used as follows to authenticate a call:

CARL Source Token Example
> curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr
OAuth2 Token Example
> curl -X GET -H "Authorization: Bearer your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr

3.1.1. Special Case of the OAuth2 Token with Assertion JWT

In the case of the OAuth2 mechanism, client authentication relies on a JWT (JSON Web Token) assertion.
The external application builds a signed JWT to prove its identity to CARL Source (OAuth2 server).
CARL Source verifies the signature, validity, and the information contained in this JWT.
If the token is valid, CARL Source returns an OAuth2 access token, which will then be used to consume CARL Source APIs.

This assertion JWT follows the specifications of RFC 7521 and RFC 7523, and can be signed:

  • either with an asymmetric key (algorithm RSASSA-PKCS1-v1_5 + SHA-256),

  • or with a shared key (Pre-Shared Key, PSK, using HMAC + SHA-256).

Its validity period is limited in order to avoid reuse risks (replay attack).
CARL Source therefore checks that the age of the JWT does not exceed the maximum value defined in the system configuration.

3.2. HTTP-BASIC authentication

Warning

HTTP BASIC authentication (Basic Authentication) is not recommended.
Please use token-based authentication instead (see section 3.1) for any production use.

Despite the risks, if you wish to authenticate in this way, you must use a CARL Source username and password.

Authentication request example
> curl -u username https://carlsource.server.com/gmaoCS02/api/auth/v1/authenticate
Enter host password for user 'username':

The -u option is used to set a username.
When the command is entered, cURL will ask for the associated password.
The syntax -u "username:password" can be used to avoid the prompt, but this leaves a trace of the password in the terminal log (which is not recommended).

It is also possible to disable this authentication mode by checking the AuthBasicDisabled system parameter in the Authentication section :

config auth carl

In this case, attempts to access using this method will return an error:

> curl -u username https://carlsource.server.com/gmaoCS02/api/auth/v1/authenticate
Enter host password for user 'username':

{
    "errors" : [ {
     "status" : "401",
     "title" : "Unauthorized",
     "detail" : "Please provide valid authentication credentials"
     } ]
}

3.3. Authentication and security during production

Beyond this tutorial, for which the curl tool is used, an application during production must invoke the authentication service using an http communication library provided by the language in which it is programmed.

One should be very careful about how to invoke this authentication service, as technically there are two different ways to pass the settings login, password and origin to the service /authenticate.

3.3.1. Authentication during production: bad practice

The first way is to pass this information as settings in the URL.
This method is very strongly discouraged for a production application.

Example of a bad practice: passing authentication settings via the URL
POST https://carlsource.server.com/gmaoCS02/api/auth/v1/authenticate?login=LOGIN&password=password&origin=ORIGIN

In so doing, critical login and password information will potentially be treated as non-critical data and exposed, especially in log files.
Although technically possible, this practice is strongly discouraged.

3.3.2. Authentication during production: good practice

It is recommended to pass the authentication settings as form data, in the body of the query, and to adjust the Content-Type accordingly using application/x-www-form-urlencoded.

Example of a good practice: passing authentication settings via the query body
POST https://carlsource.server.com/gmaoCS02/api/auth/v1/authenticate
Content-Type: application/x-www-form-urlencoded

&login=LOGIN
&password=password
&origin=ORIGIN

4. Access rights

API access rights are determined by the rights positioned on each profile in CARL Source.

An overall profile setting, named «JSON-API access» and accessible via the «General» category, governs access to the APIs.

Warning

As default, this setting is set to «Disabled», thereby preventing API access.

Access to entities via the API is then determined based on the Read/Create/Update/Delete permissions on the functionality related to that entity (other permissions are ignored).
An algorithm applies the following criteria (in order) to link an entity to its functionality:

  1. Retrieve the FunctBean.entity attribute which directly indicates whether the entity is referenced by the functionality.

  2. If the entity does not have a referenced feature: browse the relationships between entities; the entity is linked to another entity whose feature has been identified. In such cases, an entity may be indirectly referenced by several features.

  3. If, after this traversal, certain entities are still not associated with a functionality, the information must be entered in ObjectInfoBean.relatedFunctionality.

Note
  • If an entity is not associated with a functionality, it cannot be accessed via the API (this information is shown in logs when the API is first accessed).

  • Some technical entities are not available (ObjectInfoBean.apiRestRestriction setting set to NOTALLOWED) or accessible for reading only (ObjectInfoBean.apiRestRestriction setting set to READONLY).

  • If an entity is accessible for reading only, but the profile used does not have Read permission for the associated functionality, then the entity is not accessible for the profile.

The following HTTP codes are returned if the access rights are insufficient:

  • 403 – indicates that the profile does not have the necessary permissions for this entity:

    • either in terms of the overall setting «JSON-API access» (see above),

    • or in terms of permissions on the associated functionality,

    • or because there is no associated functionality.

  • 501: indicates that the entity is only accessible in read-only mode, and therefore that POST/PUT/PATCH/DELETE operations cannot be performed on it.

5. Limit

The configuration parameter ApiMaxResults indicates the maximum number of items that a page can return in a Rest API call.
The maximum value is set to 500. Indeed, this parameter directly affects the memory consumed by the application; a value that is too high could quickly lead to saturation and cause the application to stop.
When the number of returned items exceeds 500, pagination must be used.

Pagination is used to divide a large data set into several smaller "pages" to avoid loading everything at once.
Each API call reads part of the data from the database (the beans) and then transforms them into entities — the actual objects returned.
Since some filters are applied after reading the beans and some entities come from collections, the exact number of items per page may vary.

Pagination is managed using the parameters limit and offset:

  • limit specifies the number of items desired on the page (e.g. 100 results).

  • offset specifies the number of items to skip before retrieving the desired items (e.g. to go to the next page).

Examples:

Page 1: retrieve the first 100 Work Requests
curl -X GET -H "X-CS-Access-Token: your_access_token" "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?limit=100&offset=0"
Page 2: retrieve the next 100 Work Requests (from 101 to 200)
curl -X GET -H "X-CS-Access-Token: [red]#your_access_token#" "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?limit=100&offset=100"
Page 3: retrieve the next 100 Work Requests (from 201 to 300)
curl -X GET -H "X-CS-Access-Token: [red]#your_access_token#" "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?limit=100&offset=200"
Important

With the OData option, the parameters used to handle pagination are different; in this case, API calls must use $top and $skip instead of limit and offset.

Example OData API call
curl -X GET -H "X-CS-Access-Token: [red]#your_access_token#" "https://carlsource.server.com/gmaoCS02/api/odata/v1/WOPROCESS?$top=200&$skip=300

6. Business scenario: the /entities API

Now that your installation is working and you know how to access protected services using the authentication system of your choice, you will be able to interact with CARL Source business objects.

The scenario below shows how to create and manipulate work requests, a key concept of CARL Source, via the /entities API.

Technically, this is a REST - HATEOAS API, based on the Crnk library, which in turn implements the JSON-API specification.

6.1. Anatomy of a call

To get started, let’s list the existing work requests in CARL Source.
To do this, we simply need to know the code used to refer to work requests in CARL Source.
This code is mr (we will come back to this later).

Query to list work requests
> curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr
Warning

To be accessible through the API /entities, in read/edit/create/delete mode, attributes must have the Exported in XML format property checked or null in the CARL Source dictionary.

Changing the value of the Exported in XML format property
curl -X POST -i -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1?rebuildAPIs

Before we run this command, let’s take a closer look:

  • the first parameter -H 'X-CS-Access-Token" is used to specify the token previously obtained (see Token Authentication), in order to authenticate using the Custom Header Token method,

  • The rest of the PO invokes the REST service responsible for listing work requests (mr).

This URL can be broken down as follows:

  • https://carlsource.server.com: the first part of the URL corresponds to the address of the CARL Source server.

  • /gmaoCS02: indicates the context of the CARL Source web application.

  • /api: specifies that we want to access a CARL Source REST API.

  • /entities/v1/: we are calling the /entities API, and specifically the first version (/v1).

  • /mr: we wish to access the mr entity type, i.e. work requests.

If no further information is provided, CARL Source returns a list of all work requests (in JSON format).
Here is an excerpt from the response:

Example with an excerpt from the response
> curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr

HTTP/1.1 200
{
    "data" : [ {
        "id" : "DI-1",
        "type" : "mr",
        "attributes" : {
            "code" : "DI-001",
            "statusChangedDate" : "2018-10-19T15:31:21.495+02:00",
            "description" : "Chauffage / Climatisation salle de réunion direction",
            "expEnd" : "2018-10-20T15:31:21.495+02:00",
            "SRID" : 0,
            "amount" : 0.0,
            "creationDate" : "2018-10-19T15:31:21.495+02:00",
            "workRecept" : true,
            "workPriority" : "HIGH",
            "eqptBroken" : true,
            "statusCode" : "REQUEST"
        },
        "relationships" : {
            "address" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/relationships/address",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/address"
                }
            },
            "symptom" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/relationships/symptom",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/symptom"
                }
            },
            "site" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/relationships/site",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/site"
                }
            },
            "risks" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/relationships/risks",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/risks"
                }
            },
            "customer" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/relationships/customer",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/customer"
                }
            }
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1",
            "workflow-transitions" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/DI-1/workflow-transitions"
        }
    },
    {
        "id" : "DI-2",
        "type" : "mr",
        ...
    } ]
}

The /entities API complies with the JSON-API standard.
The returned JSON data are always encapsulated in an array JSON called data[].

Let us look at the structure of each mr object returned:

  • The identifier (id) and entity type (type) attributes are at the first level.

  • The business attributes are grouped in an attributes object.

  • Linked objects and collections are considers are relationships and are grouped in a relationships object.

  • Each relationship is named (e.g. risks) and consists of one links sub-object, in turn comprising two attributes:

    • related gives the URL to be called in order to retrieve the details of this relationship;

    • self gives the URL for the relationship itself (useful to manipulate the relationship itself and not the two linked objects, for example to delete the relationship without deleting either of the two linked objects).

  • Lastly, a links object, which uses the same self concept and adds a workflow-transitions attribute that can be used to move objects through their life cycle (we will come back to this aspect later).

Typical JSON structure returned by a service of the /entities CARL Source API
{
    "data" : [
        {
            "id" : <identifiant>,
            "type" : <type>,
            "attributes" : {
                <liste des attributs>
            },
            "relationships" : {
                <liste des objets et collections liés avec pour chacun les URL 'self' et 'related'>
            },
            "links" : {
                "self" : <URL du service donnant le détail de cet objet>,
                "workflow-transitions" : <URL du service donnant les futurs états possibles de cet objet au sein de son cycle de vie>
            }
        },
        <les autres objets sur le même modèle>
    ]
}
Note

The command used in this section is given as an example; it retrieves a large amount of data.
It is unlikely that an application would require so much raw data; the following section explains how to filter this data and select only items of interest.

6.2. Listing, filtering and selecting

The CARL Source /entities API is based on the Crnk framework, which follows the recommendations of the JSON-API specification. However, not everything is described by this specification.
Query-related aspects (filtering, sorting, pagination, etc.) are based on the QuerySpec API.

6.2.1. Simple filters

Here are some examples of filters that allow you to perform searches using basic operators:

Sort by creation date in descending order
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?sort=-creationDate
  1. Sort by creation date in descending order, then by name in ascending order

curl -X GET -H "X-CS-Access-Token: [red]#your_access_token#" pass:[https://][red]#carlsource.server.com/gmaoCS02#/api/entities/v1/mr?sort=-creationDate,name
  1. Results limited to the first two pages

curl -X GET -H "X-CS-Access-Token: [red]#your_access_token#" pass:[https://][red]#carlsource.server.com/gmaoCS02#/api/entities/v1/mr?sort=id&page[offset]=0&page[limit]=2
Exact search on the value of the 'name' field
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter[mr][name]=Heating / Air Conditioning in the executive meeting room
  1. LIKE (or “contains”) search on the value of the 'name' field

curl -X GET -H "X-CS-Access-Token: [red]#your_access_token#" pass:[https://][red]#carlsource.server.com/gmaoCS02#/api/entities/v1/mr?[blue]#*filter*#[mr]pass:[[][blue]#*name*#pass:[]]pass:[[][blue]#*LIKE*#pass:[]]=failure
Returns only the name of each work request
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?fields[mr]=name

6.2.2. Complex filters

 

Important

Note: The format used to describe a complex filter contains special characters (square brackets and curly braces). These characters must be encoded; otherwise, the request will be rejected
However, they will be retained in the following examples to make them easier to read.

 

It is possible to perform more complex queries by combining filters with composite logical operators. The currently supported operators are OR and AND.

Here are some examples of queries using complex filters:

Search for work requests whose code is equal to "MR01" OR whose ID is equal to "01"
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter={"OR":[{"code":"MR01"},{"id":"01"}]}
Search for work requests that involve equipment that is out of service AND has a high priority
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter={"AND":[{"eqptBroken":true},{"workPriority":"HIGH"}]}
Search for work requests whose desired end date is later than a value OR earlier than a value
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter={"OR":[{"GT":{"expEnd": "2026-01-01"}},{"LT":{"expEnd": "2026-12-31"}}]}
Search for work requests related to equipment that is broken OR unavailable OR has a high priority
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter={"OR":[{"eqptBroken":true},{"eqptUnavailable":true},{"workPriority":"HIGH"}]}

It is also possible to nest filters using composite logical operators. Here is an example:

Search for high-priority work requests OR [those involving failed equipment AND with a desired completion date later than a specified value]
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr?filter={"OR":[{"workPriority":"HIGH"},{"AND":[{"eqptBroken":true},{"GT":{"expEnd": "2026-12-31"}}]}]}

 

6.3. Creating, reading, updating and deleting

In accordance with the REST standard, the following HTTP verbs are available, each assigned to a specific role:

  • POST: create

  • GET: read

  • PATCH: update

  • DELETE: delete

6.3.1. Creation

For example, run the following command to create a work request:

POST query to create a work request, with description and priority initialized
curl -X POST -i -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data" : {
            "type" : "mr",
            "attributes" : {
                "description" : "Nouvelle demande",
                "workPriority" : "HIGH"
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/mr

In accordance with the JSON API standard, the format of the data submitted to JSON follows the structure detailed above ({ "data": {..}}), and an HTTP header sets the content type submitted -H "Content-Type: application/vnd.api+json".
 

Tip

The data can be sent through a file with the following query:
 

curl -X POST -i -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" --data-binary "@path/to/file" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr
 

Note: the file path must be preceded by the @ symbol.

The file JSON will then have the following content:

{
    "data" : {
        "type" : "mr",
        "attributes" : {
            "description" : "Nouvelle demande",
            "workPriority" : "HIGH"
        }
    }
}

 

The JSON describing the work request just created is received in response to this query, with an HTTP 201 code.
The following is an excerpt:

HTTP/1.1 201
{
    "data" : {
        "id" : "166ee780a94-1486",
        "type" : "mr",
        "attributes" : {
            "code" : "000001",
            "description" : "Nouvelle demande",
            "workPriority" : "HIGH",
            "eqptBroken" : false,
            "SRID" : 0,
            "amount" : 0.0,
            "creationDate" : "2018-11-08T17:20:10.583+01:00",
            "modifyDate" : "2018-11-08T17:20:10.600+01:00",
            "expEnd" : "2018-11-08T17:20:10.585+01:00",
            "statusChangedDate" : "2018-11-08T17:20:10.584+01:00",
            "statusCode" : "REQUEST"
            ...
        },
        "relationships" : {
            "address" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/relationships/address",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/address"
                }
            },
            "risks" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/relationships/risks",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/risks"
                }
            },
            ...
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486",
            "workflow-transitions" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions"
        }
    }
}

The value of the links.self attribute directly gives the URL to call for the details of the newly created work request.

6.3.2. Reading

To retrieve an existing object, simply add its identifier after the URL:

curl -X GET -i -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486

The response is then the same as the one obtained above following a creation: it contains the object’s details.

6.3.3. Modification

To update an existing object, the syntax is similar to that for creating and reading, but with an appropriate HTTP verb: PATCH.

curl -X PATCH -i -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data" : {
            "type" : "mr",
            "attributes" : {
                "description" : "Nouvelle demande urgente",
                "workPriority" : "VERYHIGH"
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486

6.3.4. Deleting

A similar approach is used for deleting an object: specify an identifier at the end of the URL and use the appropriate HTTP verb: DELETE.

curl -X DELETE -i -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486

6.3.5. Summary

To summarise the various actions available
  • List: GET /api/entities/<API version>/<object type code>
    + any QuerySpec options

  • Create: POST /api/entities/<API version>/<object type code>
    + a document JSON used to initialize the created object

  • Read: GET /api/entities/<API version>/<object type code>/<object identifier>

  • Update: PATCH /api/entities/<API version>/<object type code>/<object identifier>
    + a document JSON used to change the object

  • Delete: DELETE /api/entities/<API version>/<object type code>/<object identifier>

6.4. Multilingual management

6.4.1. History of multilingual management

Until version 7.3.0, the /entities API did not handle multilingual aspects (Babylon) at all. This means that the data handled by the API systematically corresponded to the data stored in the CARL Source tables (as opposed to those stored in the translation tables), and were therefore expressed in the application’s default language.

Starting with CARL Source 7.4.0, the system configuration parameter enableI18nEntitiesApi makes it possible to use the /entities API in two distinct modes:

  • a mode in which the API supports CARL Source multilingual capabilities in both read and write operations.
    This is the default mode, allowing the API to return data translated into the user’s language in read responses, and to create or modify translations in write requests.

  • a compatibility mode in which the historical API behavior is preserved, without handling multilingual aspects at all.
    In addition, support for the _locale URI parameter (already available in several CARL Source APIs) has been added to the /entities API in order to override the language of the logged-in user.

Then, in CARL Source 7.5.0, a set of new URI parameters was introduced to allow filtering and sorting on translatable elements:

  • i18nFilter : to be used instead of filter if the filter must apply to translated elements.

  • _i18nSort : false by default. If true, the sort parameter can apply to translated elements.

  • _ignoreTranslations : false by default. If true, any translations are not resolved in read or write operations.

6.4.2. Translation resolution and new meta blocks

If the system configuration parameter enableI18nEntitiesApi is enabled, translations are resolved in both read and write operations. The language in which the request is executed is determined:

  1. primarily from the _locale URI parameter value,

  2. otherwise from the language of the user logged into CARL Source at the time of the API call.

This means that if translated data exists in the requested language, it will be resolved and returned in the response.

In order to identify the language in which the returned elements are expressed, and to provide the necessary context for using this translated data, new meta blocks, compliant with the JSON:API specification, have been added to the response.

6.4.2.1. Meta blocks and attribute languages on read

We request the details of an object of type unit with identifier 100 while logged in as a French user:

curl -X GET /api/entities/v1/unit/100?fields=code,description,symbol
Response obtained
{
    "data": {
        "id": "CH",
        "type": "unit",
        "links": {
            "self": "https://carlsource.server.com/api/entities/v1/unit/100"
        },
        "meta": {
            "translatableAttributesLanguageMap": {
                "symbol": "fr",
                "description": "fr"
            },
            "entityLanguage": "fr",
            "codeReference": "CH"
        },
        "attributes": {
            "symbol": "ch",
            "code": "CH",
            "description": "Cheval-vapeur"
        }
    },
    "links": {
        "self": "https://carlsource.server.com/api/entities/v1/unit/100?fields=code%2Cdescription%2Csymbol"
    },
    "meta": {
        "requestLocale": "fr_FR"
    }
}

Then the details of the same object, with the same logged-in user, but specifying the English language:

curl -X GET /api/entities/v1/unit/100?fields=code,description,symbol&_locale=en_GB
Response obtained
{
    "data" : {
        "id": "CH",
        "type": "unit",
        "links": {
            "self": "https://carlsource.server.com/api/entities/v1/unit/100"
        },
        "meta": {
            "translatableAttributesLanguageMap": {
                "symbol": "en",
                "description": "en"
            },
            "entityLanguage": "fr",
            "codeReference": "CH"
        },
        "attributes": {
            "symbol": "hp",
            "code": "CH",
            "description": "Horsepower"
        }
    },
    "links": {
        "self": "https://carlsource.server.com/api/entities/v1/unit/100?fields=code%2Cdescription%2Csymbol&_locale=en_GB"
    },
    "meta": {
        "requestLocale": "en_GB"
    }
}
6.4.2.2. A global meta block for the request language

If we examine the content of these two responses from bottom to top, we first notice that a global meta block systematically indicates the locale in which the request was executed. Indeed, even if this may seem redundant when the locale is explicitly specified as a URI parameter, this parameter remains optional and, if absent, the locale associated with the logged-in user prevails. In this case, the request locale is implicit, so it is useful to reiterate it in the response.

6.4.2.3. Attributes translated into the request language

If the selected entity has translatable attributes, and those attributes have a translation in the requested language, then they are now resolved and included in the response.
In this context, a meta block per entity appears and provides three pieces of contextual information:

  • translatableAttributesLanguageMap indicates which attributes of the entity are translatable, and for each one, the language in which its value is expressed.

  • entityLanguage indicates the language in which the entity was created.

  • codeReference is the code as stored in the table (in the entity’s language), which can be used to retrieve the entity via a filter[code]=.

6.4.3. Creation and update of translations

If a French user creates an entity, the request and response look like this:

curl -X POST /api/entities/v1/unit
{
    "data": {
        "type": "unit",
        "attributes": {
            "code": "CH",
            "description": "Cheval-vapeur",
            "symbol": "ch",
            "decimal": "0"
        }
    }
}
Response obtained
{
    "data": {
        "id": "100",
        "type": "unit",
         "links": {
            "self": "https://carlsource.server.com/api/entities/v1/unit/100"
        },
        "meta": {
            "translatableAttributesLanguageMap": {
                "symbol": "fr",
                "description": "fr"
            },
            "entityLanguage": "fr",
            "codeReference": "CH"
        },
        "attributes": {
            "symbol": "ch",
            "UOwner": "DEMO",
            "code": "CH",
            "modifyDate": "2026-01-16T14:38:28.128+01:00",
            "description": "Cheval-vapeur",
            "persoId": null,
            "decimal": 0
        },
        "relationships": {
            "secuPolicy": {
                "links": {
                    "self": "https://carlsource.server.com/api/entities/v1/unit/100/relationships/secuPolicy",
                    "related": "https://carlsource.server.com/api/entities/v1/unit/100/secuPolicy"
                 }
            }
        }
    },
    "links": {
        "self": "https://carlsource.server.com/api/entities/v1/unit"
    },
    "meta": {
        "requestLocale": "fr_FR"
    }
}

However, if an English user executes this same request, the following response is obtained:

{
    "data": {
        "id": "100",
        "type": "unit",
        "links": {
            "self": "https://carlsource.server.com/api/entities/v1/unit/100"
        },
        "meta": {
            "translatableAttributesLanguageMap": {
                "symbol": "en",
            "description": "en"
            },
            "entityLanguage": "en",
            "codeReference": "HP"
        },
        "attributes": {
            "symbol": "hp",
            "UOwner": "DEMO",
            "code": "HP",
            "modifyDate": "2026-01-16T14:48:15.065+01:00",
            "description": "Horsepower",
            "persoId": null,
            "decimal": 0
        },
        "relationships": {
            "translations": {
                "links": {
                    "self": "https://carlsource.server.com/api/entities/v1/unit/100/relationships/translations",
                    "related": "https://carlsource.server.com/api/entities/v1/unit/100/translations"
                }
            },
            "secuPolicy": {
                "links": {
                    "self": "https://carlsource.server.com/api/entities/v1/unit/100/relationships/secuPolicy",
                    "related": "https://carlsource.server.com/api/entities/v1/unit/100/secuPolicy"
                }
            }
        }
    },
    "links": {
        "self": "https://carlsource.server.com/api/entities/v1/unit?_locale=en_GB"
    },
    "meta": {
        "requestLocale": "en_GB"
    }
}

We notice that:

  • the request language differs between the two cases,

  • translatable attributes are expressed according to that language,

  • codeReference is indeed the code with which the entity was initially created, and therefore the one to use to reference this entity via a filter[code]=.

If the entity was created by the French user and you wish to create or modify English translations, a PATCH request is sufficient.
If a French user performs this operation, the _locale=en_GB URI parameter must be specified.

curl -X PATCH /api/entities/v1/unit/100?_locale=en_GB
Response obtained
{
    "data": {
        "id": "CH",
        "type": "unit",
        "links": {
            "self": "https://carlsource.server.com/api/entities/v1/unit/100"
        },
        "meta": {
            "translatableAttributesLanguageMap": {
                "symbol": "en",
                "description": "en"
            },
            "entityLanguage": "fr",
            "codeReference": "CH"
        },
        "attributes": {
            "symbol": "hp",
            "UOwner": "DEMO",
            "code": "CH",
            "modifyDate": "2026-01-16T13:55:43.722+01:00",
            "description": "Horsepower",
            "persoId": null,
            "decimal": 0
        },
        "relationships": {
            "translations": {
                "links": {
                    "self": "https://carlsource.server.com/api/entities/v1/unit/100/relationships/translations",
                    "related": "https://carlsource.server.com/api/entities/v1/unit/100/translations"
                }
            },
            "secuPolicy": {
                "links": {
                    "self": "https://carlsource.server.com/api/entities/v1/unit/100/relationships/secuPolicy",
                    "related": "https://carlsource.server.com/api/entities/v1/unit/100/secuPolicy"
                }
            }
        }
    },
    "links": {
        "self": "https://carlsource.server.com/api/entities/v1/unit/100?_locale=en_GB"
    },
    "meta": {
        "requestLocale": "en_GB"
    }
}

6.4.4. Multilingual filtering

Filtering has evolved in several stages, detailed below.

Until CARL Source 7.2, for a request including a filter such as filter[code][EQ]=SOME_CODE:

  • The locale was never taken into account, and the search was performed only on the main table (i.e., always in the main language and never in the translation tables).

  • The attributes section contained the untranslated values as stored in the main table.

Starting with CARL Source 7.4, for a request including a filter such as filter[code][EQ]=SOME_CODE:

  • The search is performed only on the main table.

  • If the system configuration parameter enableI18nEntitiesApi is enabled, the attributes section contains translated values.

  • If the system configuration parameter enableI18nEntitiesApi is enabled, but the request includes _ignoreTranslations=true, then the attributes section contains untranslated values as stored in the main table (request-level compatibility mode).

  • If the system configuration parameter enableI18nEntitiesApi is disabled, the attributes section contains untranslated values as stored in the main table (global compatibility mode).

Starting with CARL Source 7.5, for a request including a filter such as i18nFilter[code][EQ]=SOME_CODE:

  • The search is performed on translated values.

  • The attributes section contains translated values.

Warning

To remain in historical behavior (before CARL Source 7.3) without multilingual support, you can act at two levels:

  1. At the global level, by unchecking the system configuration parameter`enableI18nEntitiesApi`.

  2. Per request, by adding the _ignoreTranslations=true URI parameter.

6.4.5. Multilingual sorting

Unlike filtering, and in accordance with the JSON:API specification, sorting cannot rely on a new parameter: it is still handled by the sort parameter. As a result, its behavior remains historically consistent: it does not take translations into account.
However, a new parameter makes it possible for sort to handle multilingual data: adding _i18nSort=true enables sorting on the translatable attribute.

  • The filter parameter becomes i18nFilter if you want it to apply to translated values.

  • However, the sort parameter remains sort, and you must add _i18nSort=true if you want it to apply to translated values.

Examples

Given the following data for the animal feature, executed by a French user.

  • Code : A

  • Description : abeille

  • Description translation : bee

 

  • Code : B

  • Description : baleine

  • Description translation : whale

 

  • Code : C

  • Description : chien

  • Description translation : dog

curl -X GET /api/entities/v1/animal
  • A, abeille

  • B, baleine

  • C, chien

curl -X GET /api/entities/v1/animal?_locale=en_GB
  • A, bee

  • B, whale

  • C, dog

curl -X GET /api/entities/v1/animal?filter[description][LIKE]=h&_locale=en_GB

*

curl -X GET /api/entities/v1/animal?i18nFilter[description][LIKE]=h&_locale=en_GB
  • B, whale

  • C, chien

curl -X GET /api/entities/v1/animal?_ignoreI18n=true&_locale=enGB
  • A, abeille

  • B, baleine

  • C, chien

curl -X GET /api/entities/v1/animal?sort=description&_locale=enGB
  • A, bee

  • B, whale

  • C, dog

curl -X GET /api/entities/v1/animal?sort=description&_i18nSort=true&_locale=enGB
  • A, bee

  • C, dog

  • B, whale

6.5. APIs outside the standard case

6.5.1. The readings API /entities/v1/measurereading

Adding readings is not supported by the standard API, as it has a special feature.
Indeed, calculating the variation as a function of the reading (and vice versa) is a special job that does not fall within the standard case of adding an entity.

An API has been created specifically to add a reading: refer to the Scenario for adding readings: the /measure-readings API chapter for a detailed explanation.

6.6. Interacting with the life cycle

Beyond CRUD interactions (create, read, update, delete), the /entities API can be used to move the status of business objects through their life cycle.
In CARL Source, the most central business objects have a life cycle: a succession of states connected together transitions.

Example: as default, a work request has its status set to Not yet taken into account when first created.
From this status, various transitions are available, each leading to a new status:

  • The Accept work request transition leads to the Awaiting start of work status.

  • The Transfer work request transition loops back to the Not yet taken into account status.

  • The Reject work request transition leads to the Rejected status.

  • The Request additional information transition leads to the Awaiting information status.

  • The Close work request transition leads to the Closed status.

Let us go back to the work request created above.
Its identifier is 166ee780a94-1486 and its status is Not yet taken into account: (corresponding to the statusCode attribute set to the value «REQUEST»).

If the data for this work request is retrieved using the following command:

curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486

The following information is returned:

{
    "data" : {
        "id" : "166ee780a94-1486",
        "type" : "mr",
        "attributes" : {
            "code" : "000005",
            "description" : "Nouvelle demande",
            "workPriority" : "HIGH",
            "statusCode" : "REQUEST"
            ...
        },
        "relationships" : {
            ...
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486",
            "workflow-transitions" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions"
        }
    }
}

The links section provides us with a link (URL) via the "workflow-transitions" property.
Calling this URL retrieves the list of all possible transitions from the current status of the work request:

curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions

As the list of transitions can be large, the filtering capabilities mentioned above can be used to restrict the list to the transitions of interest.

In this example, we wish to apply the Accept work request transition to set the work request status to Awaiting start of work. We therefore need the code corresponding to this «target» status.
This code can be obtained through the CARL Source status workflows sub-function (see Transition codes and status codes): In fact, the code corresponding to the Awaiting start of work status is AWAITINGREAL.
We can now restrict the list of transitions to those whose nextStepCode is AWAITINGREAL:

curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions?filter[nextStepCode]=AWAITINGREAL
Response obtained:
HTTP/1.1 200
{
    "data" : [ {
        "id" : "M1B:com.carl.xnet.system.status.TransitionParameters",
        "type" : "workflow-transitions",
        "attributes" : {
            "nextStepCode" : "AWAITINGREAL",
            "transitionParameters" : null
        },
        "relationships" : {
            "transition" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/relationships/transition",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/transition"
                }
            }
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters"
        }
    },
    {
        "id" : "M1:com.carl.xnet.system.status.TransitionParameters",
        "type" : "workflow-transitions",
        "attributes" : {
            "nextStepCode" : "AWAITINGREAL",
            "transitionParameters" : null
        },
        "relationships" : {
            "transition" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1:com.carl.xnet.system.status.TransitionParameters/relationships/transition",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1:com.carl.xnet.system.status.TransitionParameters/transition"
                }
            }
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1:com.carl.xnet.system.status.TransitionParameters"
        }
    } ]
}

We can see in the response above that there are two transitions that would result in the work order status changing to Awaiting start of work.
We can obtain the details of each transition via relationships.transition.links.related:

  • /api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/transition

  • /api/entities/v1/workflow-transitions/M1:com.carl.xnet.system.status.TransitionParameters/transition

Call to retrieve the details of the first transition (M1B:com.carl.xnet.system.status.TransitionParameters):

curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/transition
Response obtained:
HTTP/1.1 200
{
    "data" : {
        "id" : "M1B",
        "type" : "mrreqawaintingrealtransition",
        "attributes" : {
            "ordering" : 1,
            "description" : "Accepter la DI",
            "automatic" : true,
            "pageId" : null,
            "transitionFamily" : null
        },
        "relationships" : {
            "msgTemplate" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/relationships/msgTemplate",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/msgTemplate"
                }
            },
            "nextStep" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/relationships/nextStep",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/nextStep"
                }
            },
            "step" : {
                "links" : {
                    "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/relationships/step",
                    "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B/step"
                }
            }
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mrreqawaintingrealtransition/M1B"
        }
    }
}

The transition details show that the transition is automatic ("automatic": true): it can therefore be called with no settings.
=> We can apply this transition to our work request.

To perform this status transition, we must send a POST request to the workflow-transitions URL of our work request:

curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json, Accept: application/vnd.api+json" \
     -d '{
        "data" : {
            "id" : "M1B:com.carl.xnet.system.status.TransitionParameters",
            "type" : "workflow-transitions",
            "attributes" : {
                "nextStepCode" : "AWAITINGREAL",
                "transitionParameters" : null
            },
            "relationships" : {
                "transition" : {
                    "links" : {
                        "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/relationships/transition",
                        "related" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters/transition"
                    }
                }
            },
            "links" : {
                "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/workflow-transitions/M1B:com.carl.xnet.system.status.TransitionParameters"
            }
        }
    }' \
    https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions

The JSON returned is of no interest to us (it is only the details of the transition that took place).
However, if we request the work request details again, we can see that its statusCode attribute has changed from REQUEST to AWAITINGREAL:

curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486?fields[mr]=code,description,statusCode
Response obtained:
HTTP/1.1 200
{
    "data" : {
        "id" : "166ee780a94-1486",
        "type" : "mr",
        "attributes" : {
            "code" : "000001",
            "description" : "Nouvelle demande urgente",
            "statusCode" : "AWAITINGREAL"
        },
        "links" : {
            "self" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486",
            "workflow-transitions" : "https://carlsource.server.com/gmaoCS02/api/entities/v1/mr/166ee780a94-1486/workflow-transitions"
        }
    }
}

6.7. CARL Source dictionary

The CARL Source /entities API is self-describing: the JSON objects returned in the HTTP response include URLs that can be directly invoked in order to be able to "browse" through an object graph to find out about it.
However, there are limits to this: you have to know the code of the type of object you want to manipulate (mr in our examples).
Similarly, while it is possible to discover the available transitions from the current status of an object, the codes of the potential statuses of an object are not provided by the API.

These codes are available from the Dictionary function in CARL Source, and specifically the Status workflow sub-function (System menu).

6.7.1. Object type codes

Objects in the dictionary describe all CARL Source objects, regardless of their type, but not all objects can be manipulated via the /entities API: only objects whose category is Entity (objectType = BEAN) can be manipulated – this represents more than 500 objects.

Note

There are a few rare exceptions, in that some particularly technical objects (specific to the internal operation of CARL Source) are:

  • either excluded from the manipulable objects,

  • or are accessible only in read-only mode (see the value of the apiRestriction attribute on dictionary objects).

From these objects, the object type code to be used with the API is very easy to determine: it corresponds to the object code value, in lower case.

A few examples

  • For the dictionary object Work orders, the code is WO: the code to be used in the API is thus wo.
    => Example: https://carlsource.server.com/gmaoCS02/api/entities/v1/wo lists the work orders defined in CARL Source.

  • For the dictionary object Customer, the code is CUSTOMER: the code to be used in the API is thus customer.
    => Example: https://carlsource.server.com/gmaoCS02/api/entities/v1/customer lists the clients defined in CARL Source.

  • For the dictionary object Cost center, the code is COSTCENTER: the code to be used in the API is thus costcenter.
    => Example: https://carlsource.server.com/gmaoCS02/api/entities/v1/costcenter lists the cost centers defined in CARL Source.

  • For the dictionary object Technician, the code is TECHNICIAN: the code to be used in the API is thus technician.
    => Example: https://carlsource.server.com/gmaoCS02/api/entities/v1/technician lists the technicians defined in CARL Source.

  • And so on.

6.7.2. Transition codes and status codes

We have seen that transitions of an object between two statuses (via the workflow-transitions property) can easily be discovered via URLs returned by the API.
However, the various possible status values for a CARL Source object cannot be discovered in the same way.
To view these statuses, the Workflow statuses sub-function of the CARL Source dictionary can be consulted.

This can be used, for example, to enter a work request whose statusCode attribute is REQUEST:

  • is Waiting to be taken into account,

  • the next most likely status is AWAITINGREAL (Awaiting start of work),

  • and the new status can be reached by applying the Accept the WR transition.

7. IIOT scenario: Make objects connected with CARL Source interact

This section explains how to make objects connected with CARL Source interact.

Note

In the following queries, values in red are to be changed according to your configuration or your needs.
The queries were defined based on a HTTP-BASIC authentication. For token authentication, they will have to be adapted by following the procedure of Token Authentication.

7.1. Context

7.1.1. Pairing between a sensor and a reading point

A sensor may be associated with one or more CARL Source reading points. To do so, an entity was created with the name of SensorPairing.
This entity represents the pairing between a sensor and a reading point. Consequently, this means that a pairing must have 1 reading point and a reading point may have 0 or 1 pairing.
Thus, all the pairings represent the various associations of a sensor with CARL Source reading points.

The SensorPairing entity contains the following attributes:

Attribute Type Required? Description

description

Alphanumeric

No

Description

databaseName

Alphanumeric

Yes

Name of the database where the sensor is managed

measurement

Alphanumeric

Yes

Name of the reading in which the sensor is managed

sensorTags

List of SensorTags

Yes

List of tags

field

Alphanumeric

Yes

Reading

dateOfPairing

Date

Yes

Pairing date

measurePoint

MeasurePoint

Yes

Associated reading point

7.1.2. The tags associated with a pairing

A pairing must have 1 or more tags. A SensorTag entity has therefore been created to fulfil this role.
This entity consists of a key/value combination and is associated with a pairing. It contains the following attributes:

Attribute Type Required? Description

tagKey

Alphanumeric

Yes

Key

tagValue

Alphanumeric

Yes

Value

sensorPairing

SensorPairing

Yes

Associated pairing

As default, two tags are created automatically when a pairing is created. These tags represent the reading point and the associated equipment:

Key Value

MEASURE_POINT

CARL Source id of the reading point

EQUIPMENT

CARL Source id of the equipment

7.2. Create, read, update, and delete a sensor pairing

7.2.1. Creation

POST query creating a pairing between a sensor and a reading point
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data": {
            "type": "sensorpairing",
            "attributes": {
                "description": "mon premier appairage",
                "databaseName": "nom de la base",
                "measurement": "nom de la mesure",
                "field": "mesure",
                "dateOfPairing": "2019-12-10T19:10:00.000+02:00"
            },
            "relationships": {
                "measurePoint": {
                    "data": {
                        "type": "measurepoint",
                        "id": "measurepoint_id"
                    }
                }
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing

The JSON describing the pairing just created is received in response to this query, with an HTTP 201 code.

Note

The two MEASURE_POINT and EQUIPMENT tags have also been created.

7.2.2. Reading

7.2.2.1. List all pairings
GET query retrieving the list of all pairings
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/
7.2.2.2. Lists all pairings between a sensor and its reading points
GET query retrieving the list of all pairings of a sensor (retrieves only the id of the pairings)
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag?fields=sensorPairing&filter[tagKey]=SENSOR&filter[tagValue]=sensor_name
GET query retrieving the list of all pairings of a sensor (including all the attributes of each pairing in the result)
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag?include=sensorPairing&filter[tagKey]=SENSOR&filter[tagValue]=sensor_name
7.2.2.3. List all the reading points of a sensor

Here, the reading point is not directly linked to the tag: it must be included in the query by going through the pairing.
In the returned result, the list of the sensor’s reading points will be located in the tag «included»: [...].

GET query retrieving the list of all reading points of a sensor
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag?include=sensorPairing.measurePoint&filter[tagKey]=SENSOR&filter[tagValue]=intensity
7.2.2.4. Retrieve the details of a pairing
GET query retrieving an existing pairing
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/pairing_id
7.2.2.5. Retrieve the reading point of a pairing
GET query retrieving the reading point of a pairing
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/pairing_id/relationships/measurePoint

7.2.3. Modification

The syntax is close to that of creation; the url simply needs to be pointed to the pairing’s id and only the attributes/relationships to be changed are used.
Example:

PATCH query changing an existing pairing
curl -X PATCH -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data": {
            "type": "sensorpairing",
            "attributes": {
                "description": "mon premier appairage modifié",
                "field": "mesure2",
                "dateOfPairing": "2019-12-10T20:10:00.000+02:00"
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/pairing_id

7.2.4. Deleting

DELETE query deleting an existing pairing
curl -X DELETE -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/pairing_id

7.3. Create, read, update, and delete a tag associated with a sensor pairing

7.3.1. Creation

POST query creating a tag on a pairing
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data": {
            "type": "sensortag",
            "attributes": {
              "tagKey": "SENSOR",
              "tagValue": "engine_temp"
            },
            "relationships": {
                "sensorPairing": {
                    "data": {
                        "type": "sensorpairing",
                        "id": "pairing_id"
                    }
                }
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag

The JSON describing the tag just created is received in response to this query, with an HTTP code 201.

7.3.2. Reading

7.3.2.1. List all tags
GET query retrieving the list of all tags
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag/
7.3.2.2. List all tags filtered by key
GET query retrieving the list of all tags filtered by MEASURE_POINT key
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag?fields=tagKey,tagValue,sensorPairing&filter[tagKey]=MEASURE_POINT
7.3.2.3. List all tags of a pairing
GET query retrieving the list of all tags of a pairing
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensorpairing/pairing_id/sensorTags?fields=tagKey,tagValue
7.3.2.4. Retrieve the details of a tag
GET query retrieving the existing tag
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag/tag_id

7.3.3. Modification

The syntax is close to that of creation; the url simply needs to be pointed to the tag’s id and only the attributes/relationships to be changed are used.
Example:

PATCH query changing an existing tag
curl -X PATCH -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data": {
            "type": "sensortag",
            "attributes": {
              "tagValue": "intensity"
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag/tag_id

7.3.4. Deleting

DELETE query deleting an existing tag
curl -X DELETE -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/sensortag/tag_id

7.4. Create and read a reading via a sensor pairing

7.4.1. Creation

POST query creating a reading from a pairing
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
     -d '{
        "data": {
            "measure": 3, OU "variation": 3,
            "measuredAt": "2023-04-17T15:07:06",
            "sensorPairing": {
                "id": "pairing_id"
            }
        }
     }' \
     https://carlsource.server.com/gmaoCS02/api/measure-readings/v1/add

The JSON describing the pairing just created is received in response to this query, with an HTTP 201 code.

Note

The value of the "Source" attribute is set to 3 (IOT).
The value of the "Description" attribute reflects the concatenation of the pairing’s tags.
Example: MEASURE_POINT=measurepoint_id;EQUIPMENT=equipment_id;SENSOR=intensity;.

The two MEASURE_POINT and EQUIPMENT tags have also been created.

Tip

It is also possible to add a reading list.
For a detailed explanation: refer to chapter Scenario for adding readings: the /measure-readings API.

7.4.2. Reading

7.4.2.1. List all the readings of a sensor

In the example below, we list all the readings of the "intensity" sensor.
The "fields" variable only displays the requested fields to optimise the result for useful attributes, but it can be removed from the query.

GET query retrieving the list of all readings of a sensor
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/measurereading?fields=measure,variation,dateMeasure,description,measurePoint,sensorPairing&filter[measurereading][description][LIKE]=SENSOR=intensity
Note

This query can be tailored to filter readings according to concatenated pairing tags in the description of readings.
To do so, SENSOR=intensity simply needs to be replaced with MEASURE_POINT=measurepoint_id, or EQUIPMENT=equipment_id, and so on.

7.4.2.2. List all readings of a pairing
GET query retrieving the list of all readings of a pairing
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/measurereading?filter[sensorPairing.id]=pairing_id
7.4.2.3. List all readings of a reading point
GET query retrieving the list of all readings of a reading point
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/measurereading?filter[measurePoint.id]=measurepoint_id
7.4.2.4. Retrieve the details of a reading
GET query retrieving the existing reading
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/entities/v1/measurereading/measurereading_id

8. Scenario for using linked documents: the API /ui/v1/documents

As the API /ui/v1/documents was created primarily for use by the application’s HMIs, its location is in /ui/v1.
It can, however, be used in a non-HMI context by an external application.

8.1. Data model

8.1.1. Entity Java™ class name

Unlike generic JSON:APIs that allow for entity handling, this API requires that we directly specify the Java™ class name of the entity type on which we want to handle documents.
To obtain this class name simply you can query the application via a JSON-API call.

Example to obtain the Java™ class name for the Work order entity whose code is WO
curl -X GET -H "X-CS-Access-Token: your_access_token" \
    https://carlsource.server.com/gmaoCS02/api/entities/v1/objectinfo?"filter[code]=WO&fields=typeName"
Response obtained
{
  "data": [
    {
      "id": "WO",
      "type": "objectinfo",
      "links": {
        "self": "https://carlsource.server.com/gmaoCS02/api/entities/v1/objectinfo/WO"
      },
      "attributes": {
        "typeName": "com.carl.xnet.works.backend.bean.WOBean"
      }
    }
  ],
  "links": {
    "self": "code=WO&fields=typeName"
  }
}

8.1.2. Types of linked documents

In the CARL Source application, documents linked to an entity are classified by document type: a contract, a technical diagram, an icon, a building map background. The type is not a file format type (PNG, JPEG, PDF, Word, etc.) but a category related to their use.

These document types can be accessed from the "Document type" feature of the "System" module. This is the code for the document type that is used in the linked documents API.

8.2. Uploading a linked document

The API /ui/v1/documents/entity/upload/<entity-class-name>/<entity-id> is used to upload a new document and link it to the entity whose type (Java™ class name) and identifier are given. The content of the query is in the multipart/form-data format, the same as what is used by a browser to send a file.

Example to add a PDF document to the work order identified by 17c30872770-7c:
curl -X POST -H "X-CS-Access-Token: your_access_token" \
    -F "type=DOC" \
    -F "description=Nouveau document" \
    -F "file=@NouveauDoc.pdf" \
    https://carlsource.server.com/gmaoCS02/api/ui/v1/documents/entity/upload/com.carl.xnet.works.backend.bean.WOBean/17c30872770-7c
Response obtained
{
    "data": [
        {
            "type": "documents",
            "id": "17c30872770-3336",
            "attributes": {
                "fileName": "NouveauDoc.pdf",
                "code": "DOC-00005",
                "description": "Nouveau document",
                "type": "DOC"
            },
            "links": {
                "download": "https://carlsource.server.com/gmaoCS02/download/servlet/NouveauDoc.pdf?docid\u003d17c30872770-3337\u0026version\u003d0"
            }
        }
    ]
}

Additional settings:

  • code (optional): the code of the linked document to be created. While the automatic coding is used as default, it can also be defined. Example: code=CONTRAT-0001.

Important

The download link returned by the API should not be used to download the document at this time.
It returns a deprecated value used only by CARL Source HMIs and will eventually be replaced by a different link.
To download the linked document, you must use the download API specified below.

8.3. Downloading a linked document

To download a linked document, use the /ui/v1/documents/download/<document-id> API.

Example for downloading the document added above and whose identifier is 17c30872770-3336
curl -X GET -H "X-CS-Access-Token: your_access_token" --output "doc.pdf" \
    https://carlsource.server.com/gmaoCS02/api/ui/v1/documents/download/17c30872770-3336

8.4. Listing the documents locked to an entity

To retrieve the list of documents linked to an entity, use the API /ui/v1/documents/entity/<entity-class-name>/<entity-id>.

Example for listing the documents linked to the work order identified by 17c30872770-7c
curl -X GET -H "X-CS-Access-Token: your_access_token" --basic \
    https://carlsource.server.com/gmaoCS02/api/ui/v1/documents/entity/com.carl.xnet.works.backend.bean.WOBean/17c30872770-7c
Response obtained
{
    "data": [
        {
            "type": "documents",
            "id": "17c30872770-3ca5",
            "attributes": {
                "fileName": "Photo.jpg",
                "code": "DOC-00008",
                "description": "Photo.jpg",
                "type": "IMG"
            },
            "links": {
                "download": "https://carlsource.server.com/gmaoCS02/download/servlet/Photo.jpg?..."
            }
        },
        {
            "type": "documents",
            "id": "17c30872770-3ca4",
            "attributes": {
                "fileName": "Manuel technique.pdf",
                "code": "DOC-00007",
                "description": "Manuel technique.pdf",
                "type": "PLAN"
            },
            "links": {
                "download": "https://carlsource.server.com/gmaoCS02/download/servlet/Manuel+technique.pdf?..."
            }
        },
        {
            "type": "documents",
            "id": "17c30872770-3ca6",
            "attributes": {
                "fileName": "Contrat.pdf",
                "code": "DOC-00009",
                "description": "Contrat.pdf",
                "type": "DOC"
            },
            "links": {
                "download": "https://carlsource.server.com/gmaoCS02/download/servlet/Contrat.pdf?..."
            }
        }
    ],
    "meta": {
        "isEntityDocumentable": true,
        "numberOfDocumentsInWidget": 3,
        "hasMoreResults": false,
        "canUploadDocuments": true,
        "canReadDocuments": true
    },
    "included": [
        {
            "type": "document-type",
            "id": "DOC",
            "attributes": {
                "code": "DOC",
                "description": "Textes, contrats"
            }
        },
        ...
    ]
}

The response also provides (via the sections meta and included) a number of additional useful information for a HMI:

  • the entity supports the linked documents,

  • the user can upload or download linked documents for that entity,

  • as well as the list of document types with their names.

Important

As mentioned above for the API for uploading a linked document, the download link should not be considered and not used as it is likely to change.

Additional filter settings:

  • type (optional): a comma-separated list of document types. Example: type=IMG,ICON.

  • pictureType (optional): a boolean used to filter the results according to the characterization of document types as being (or not) images (see the "Document type" feature of the "System") module. Example: pictureType=true.

9. Equipment import scenario: the API /import-equipment

The import-equipment API allows you to globally import equipment into CARL Source, and then update it after an initial import.
This API has a link with the functions of importing equipment for maps and building plans; for BIM, it is located with the REST APIs dedicated to the GIS: /gis/v1/import-equipment.

The import takes place in two steps:

  1. Use of REST APIs to import equipment descriptions into the reference table: CSGI_IMP_EQUIPMENT;

  2. Use of the GISIMPORTJOB equipment import process, in the CARL Source feature for automatic jobs.

9.1. Right to use the API

The use of this API calls for the user with whom the API is invoked to have the required profile rights. The API is controlled by the profile right: Equipment / Importing equipment.

9.2. Insert, change, or delete equipment descriptions in the import table

The API /gis/v1/import-equipment/apply-batch-operations allows global changes to be made to the import table.

This API can be used to send a POST query in the JSON format (Media-Type: application/json), a list of operations to be performed on the import table.

Example of content sent in the body of the POST query
[
    {
        "action": "CREATE",
        "equipment": {"id":"1", "structureId":"MATERIAL", "projectGuid":"18"}
    },
    {
        "action": "DELETE",
        "equipment": {"id":"2"}
    }
]

The actions available for the equipment description are the following:

Action Description

CREATE

The import line is created (SYNCH_DATE = now) with the provided values. The version is set to 0.

UPDATE

The import line is updated (SYNCH_DATE = now) with the provided values. The version is incremented.

SYNC

The import line is marked as updated (SYNCH_DATE = now). The version is incremented.

DELETE

The import line is marked for deletion (SYNCH_DELETE = true). The version is incremented.

The corresponding fields for the equipment description are as follows:

Field Type (Format or Length) Operation Description

id

Alphanumeric (33)

CREATE, UPDATE, SYNC, DELETE

Identifier of the equipment in the import table

code

Alphanumeric (20)

CREATE

Code of the equipment to be imported (business identifier)

projectGuid

Alphanumeric (40)

CREATE

BIM project identifier (GUID)

description

Alphanumeric (60)

CREATE, UPDATE

Description of the equipment to be imported (name)

structureId

Alphanumeric (40)

CREATE, UPDATE

Identifier of the structure type

parentId

Alphanumeric (33)

CREATE, UPDATE

Identifier of the parent equipment in the import table

ifcClass

Alphanumeric (255)

CREATE, UPDATE

IFC class

attributes

Alphanumeric (JSON)

CREATE, UPDATE

Generic object attributes (for example from IFC)

patternCode

Alphanumeric (20)

CREATE, UPDATE

Code of an item or template for the equipment

capacity, levelNumber

Numeric (integer)

CREATE, UPDATE

Occupancy capacity, Floor number

sul, area, groundArea

Numeric

CREATE, UPDATE

Useful area, Floor area, Land area

use, erpClass, erpCategory

Alphanumeric (255)

CREATE, UPDATE

Use, Public building classification, Public building category

pathDwf, pathDwg

Alphanumeric (255)

CREATE, UPDATE

Relative path of the DWF in the library, Original DWG name

geom

Alphanumeric (EWKT)

CREATE, UPDATE

Geometry (point, line, or polygon)

xtrabool01, xtrabool02, xtrabool03

Boolean

CREATE, UPDATE

Free boolean fields

xtradate01, xtradate02, xtradate03

Alphanumeric (ISO8601 date/time)

CREATE, UPDATE

Free date and time fields

xtranum01, xtranum02, xtranum03

Numeric

CREATE, UPDATE

Free numerical fields

xtratxt01, xtratxt02, xtratxt03, xtratxt04, xtratxt05, xtratxt06, xtratxt07, xtratxt08, xtratxt09, xtratxt10

Alphanumeric (255)

CREATE, UPDATE

Free text fields

Warning

The use of this API calls for the user to have all the rights for Creation, Change, Deletion in the profile right: Equipment / Importing equipment.
Even if you only want to perform one type of operation, the user must have all 3 rights for API access to be allowed.

POST query inserting the description of an equipment in the import table
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/json"  --data-binary "@path/to/file" https://carlsource.server.com/gmaoCS02/api/gis/v1/import-equipment/apply-batch-operations
Sample content of the JSON file
[
    {
        "action": "CREATE",
        "equipment": {
            "id":"1254",
            "code":"B2",
            "description":"Bat 2",
            "structureId":"BUILDING",
            "ifcClass":"IFCBUILDING",
            "projectGuid":"GUID2",
            "area":1200,
            "attributes":"{attr1:0}"
        }
    },
    {
        "action": "UPDATE",
        "equipment": {
            "id":"125",
            "description":"Bat 1 - new description",
            "structureId":"BUILDING",
            "area":1750
        }
    },
    {
        "action": "SYNC",
        "equipment": {
            "id":"12"
        }
    },
    {
        "action": "DELETE",
        "equipment": {
            "id":"123"
        }
    }
]
Important

Once the query has been successfully run, the GISIMPORTJOB equipment import process has to be started in CARL Source from the "Automatic jobs" feature.

9.3. Retrieve the descriptions of the equipment already included in the import table

The API /gis/v1/import-equipment/stream-equipments/{bimprojectguid} allows you to retrieve all the lines of the import table associated with a project referenced by its bimprojectguid.

The result is returned in the ndjson format (Media-Type: application/x-ndjson) : each record is converted to JSON format on a single line, and each line is separated by the character: \n.

GET query retrieving the contents of the import table for the GUID1 project
curl -X GET -H "X-CS-Access-Token: your_access_token" https://carlsource.server.com/gmaoCS02/api/gis/v1/import-equipment/stream-equipments/GUID1
Response obtained
HTTP/1.1 200

{"id": "1","code": "B1","description": "New building","area": 1200.0,"structureId": "BUILDING","attributes": "{attr1:0}","ifcClass": "IFCBUILDING"}
{"id": "2","code": "B2","description": "Building 2","area": 900.0,"structureId": "BUILDING","attributes": "{attr1:0}","ifcClass": "IFCBUILDING"}
Warning

The use of this API calls for the user to have Read rights in the profile right: Equipment / Importing equipment.

10. Scenario for using indicators: the API /ui/v1/indicators

The API /ui/v1/indicators allows you to retrieve the value of an indicator while allowing the values of the criteria of this indicator to be varied.

10.1. Creating an indicator

To be usable, this API calls for the creation of an indicator. Both a filter type and a query type indicator can be created. Note that you can vary the value of the criteria on an indicator of the filter type.

The filter can be created from a CARL Source search screen (supplemented, if applicable, by an advanced filter) using the Transform to indicator action.

In the rest of this scenario, an indicator based on the search bean MRSELBean is created. This indicator has a filter criterion based on the status (which is part of the search bean) and two custom criteria: one based on the field xtraTxt01 and another on the field externalEntityId.
Note that you can change the filter description (which will correspond to the value used to identify the filter in API queries) in the advanced filter editing screen. However, this description cannot be changed in the indicator’s edit screen afterwards.

10.2. Retrieving indicator information

This part is based on the APIs for entities in the JSON:API format using the indicator type.
In this case, we retrieve the information on the indicator starting from its code and also including its criteria:

curl -X GET -H "X-CS-Access-Token: your_access_token" \
    https://carlsource.server.com/gmaoCS02/api/entities/v1/indicator?include=criteria&filter[code]=IND_MR_CUSTOM
Response obtained (the "links" and "relationships" parts, as well as some attributes are excluded from this example for the sake of brevity):
{
  "data": [
    {
      "id": "17c57530346-f01",
      "type": "indicator",
      "attributes": {
        "code": "IND_MR_CUSTOM",
        "description": "Texte pour IND_MR_CUSTOM",
        "type": "FILTER",
        "targetForm": "MR_SELId",
        "dataBean": "com.carl.xnet.works.backend.bean.MRBean",
        "searchBean": "com.carl.xnet.works.backend.search.MRSELBean"
      }
    }
  ],
  "included": [
    {
      "id": "17c57530346-dee",
      "type": "indicatorcriterion",
      "attributes": {
        "criterion": "status",
        "description": "status",
        "criterionValue": "[REQUEST,WAITINFO,AWAITINGREAL]",
      }
    },
    {
      "id": "17c57530346-def",
      "type": "indicatorcriterion",
      "attributes": {
        "description": "xtraTxt01",
        "criterionValue": "123456",
        "operator": 6,
        "property": "xtraTxt01"
      }
    },
    {
      "id": "17c57530346-df1",
      "type": "indicatorcriterion",
      "attributes": {
        "description": "externalEntityId",
        "criterionValue": "12",
        "operator": 6,
        "property": "eqpt.externalEntityId",
      }
    }
  ]
}

10.3. Retrieving the value of this indicator with the default criteria

The following call retrieves the current value of the indicator without changing the values of the indicator criteria.
Note that a recalculation is forced at each call (even if the indicator’s refresh information is other than 0).

curl -X POST -i -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
    "code": "IND_MR_CUSTOM"
    }' \
https://carlsource.server.com/gmaoCS02/api/ui/v1/indicators/values
Response obtained:
{
  "data": [
    {
      "type": "com.carl.xnet.analyse.backend.bean.indicator",
      // l’identifiant est retourné, que l’on passe le code ou l’identifiant en paramètre
      "id": "17c57530346-f01",
      "attributes": {
        "values": [
          {
            "value": 42.0
          }
        ]
      }
    }
  ]
}
Note

The indicator identifier can be passed rather than its code by replacing the code setting by id.

10.4. Retrieving the value of this indicator with a changed criterion

You can then change the value of a filter criterion (in this case: externalEntityId).
In the following example, two different values are passed in the same call:

curl -X POST -i -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
    "code": "IND_MR_CUSTOM",
    "filters":[
    {
        "filterId": "1",
        "criteria": [
        {
            "name": "externalEntityId",
            "value":"first entity"
        }
        ]
    },
    {
        "filterId": "2",
        "criteria": [
        {
            "name": "externalEntityId",
            "value":"other entity"
        }
        ]
    }
    ]
}' \
https://carlsource.server.com/gmaoCS02/api/ui/v1/indicators/values
Response obtained:
{
  "data": [
    {
      "type": "com.carl.xnet.analyse.backend.bean.indicator",
      "id": "17c57530346-f01",
      "attributes": {
        "values": [
          {
            "filterId": "1",
            "value": 10.0
          },
          {
            "filterId": "2",
            "value": 21.0
          }
        ]
      }
    }
  ]
}

In this case, the response obtained indicates the identifier of the filter passed as a setting together with the associated value.

Note

If the indicator query is complex (e.g., table loaded, filter criteria not indexed), avoid asking for too many values at once: this would result in a significant response time.
It is up to the client application to find the right compromise between "number of values" and "number of queries".
Note that the number of values requested in a single command is limited by the system setting ApiMaxResults.

10.5. Retrieving the value of this indicator with several changed criteria

Several filter criteria can also be varied.
For example:

curl -X POST -i -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
    "code": "IND_MR_CUSTOM",
    "filters":[
    {
        "filterId": "1",
        "criteria": [
        {
            "name": "externalEntityId",
            "value":"first entity"
        },
        {
            "name": "xtraTxt01",
            "value":"a value for xtraTxt01"
        }
        ]
    }
    ]
}' \
https://carlsource.server.com/gmaoCS02/api/ui/v1/indicators/values
Response obtained:
{
  "data": [
    {
      "type": "com.carl.xnet.analyse.backend.bean.indicator",
      "id": "17c57530346-f01",
      "attributes": {
        "values": [
          {
            "filterId": "1",
            "value": 13.0
          }
        ]
      }
    }
  ]
}

11. Scenario for adding readings: the /measure-readings API

The /measure-readings API lets you add one or more meter readings.

11.1. Rights to use the API

The use of this API calls for the user with whom the API is invoked to have the required profile rights.
The API is controlled by the profile right: Equipment/ Reading.

11.2. Insert / Read readings

11.2.1. Insert a reading

The /measure-readings/v1/add API can be used to send a POST query in JSON format (Media-Type: application/json), a reading at a reading point.

Example of content sent in the body of the POST query
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
    "data": {
        "origin": "AUTO",
        "measure": 10000, OU "variation": 10,
        "measuredAt": "2023-04-17T15:07:06",
        "measurePoint": {
            "id": "6" OU "code": "CPT-KM-02"
        }
    }
}' \
https://carlsource.server.com/gmaoCS02/api/measure-readings/v1/add

The corresponding fields for the reading description are as follows:

Field Type (Format or Length) Description Required / Optional

origin

Alphanumeric

Reading source code (MANUAL, AUTO, IOT)

Required if measurePoint is entered.
Optional (as it will be forced to IOT) if sensorPairing is entered.

measure

Numeric

Reading value

Required if variation not entered.
Leave blank if variation is entered.

variation

Numeric

Reading variation

Required if measure not entered.
Leave blank if measure is entered.

measuredAt

Date

Reading date

Required

correction

Boolean

If this entails a correction

Optional

repercussion

Boolean

If this entails a repercussion

Optional

description

Alphanumeric (60)

Reading description

Optional

measurePoint

Reference reading point

Required if sensorPairing not entered.
Leave blank if sensorPairing is entered.

sensorPairing

Reference sensor pairing

Required if measurePoint not entered.
Leave blank if measurePoint is entered.

Warning

While the use of measure or variation is required for the reading to be added, the two attributes must not be entered simultaneously.

While the use of measurePoint or sensorPairing is required for the reading to be added, the two references must not be entered simultaneously (as sensorPairing contains measurePoint).

The corresponding fields for the reference measuring point description are as follows:

Field Type (Format or Length) Description

code

Alphanumeric (20)

Reading point code (leave blank if id is specified)

id

Alphanumeric (33)

Reading point Id (leave blank if code is specified)

Warning

While the use of code or id is required for the reading to have a reference reading point, the two attributes must not be entered simultaneously.

The corresponding fields for the reference sensor pairing description are as follows:

Field Type (Format or Length) Description

id

Alphanumeric (33)

Sensor pairing id

Response obtained
HTTP/1.1 201 Created
{
    "data": {
        "id": "18ad0a4654d-8",
        "variation": 0.0,
        "measure": 10000.0,
        "measuredAt": "2023-04-17T15:07:06.000",
        "correction": false,
        "repercussion": false,
        "origin": "AUTO",
        "measurePoint": {
            "id": "6"
        },
        "modifyDate": "2023-09-26T10:41:53.996",
        "noChrono": false
    }
}

11.2.2. Insert a meter readings list

The /measure-readings/v1/add-all API allows you to send a POST query in JSON format (Media-Type: application/json), a list of meter readings at one or more reading points.

Note

This list lets you add meter readings for various reading points.
Meter readings cannot be ordered, as the job will sort them via the measuredAt attribute .

Example of content sent in the body of the POST query
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
    -d '{
        "data":[
            {
                "origin": "AUTO",
                "variation": 5,
                "measuredAt": "2023-05-18T15:59:06",
                "measurePoint": {
                    "code": "CPT-KM-02"
                }
            },
            {
                "origin": "MANUAL",
                "measure": 10,
                "measuredAt": "2023-05-18T16:57:06",
                "measurePoint": {
                    "id": "12"
                }
            },
            {
                "origin": "AUTO",
                "measure": 11000,
                "measuredAt": "2023-05-18T15:57:06",
                "measurePoint": {
                    "code": "CPT-KM-02"
                }
            }
        ]
}' \
https://carlsource.server.com/gmaoCS02/api/measure-readings/v1/add-all
Note

The fields to be filled in are the same as those in the /measure-readings/v1/add API.
The difference lies in the action to be called (add-all) and in the formatting of the content: data between square brackets [ ].

Response obtained
HTTP/1.1 201 Created
{
    "data": [
        {
            "id": "18ad0e3e436-4e4",
            "variation": 0.0,
            "measure": 10.0,
            "measuredAt": "2023-05-18T16:57:06.000",
            "correction": false,
            "repercussion": false,
            "origin": "MANUAL",
            "measurePoint": {
                "id": "12"
            },
            "modifyDate": "2023-09-26T15:11:51.219",
            "noChrono": false
        },
        {
            "id": "18ad0e3e436-4e6",
            "variation": 1000.0,
            "measure": 11000.0,
            "measuredAt": "2023-05-18T15:57:06.000",
            "correction": false,
            "repercussion": false,
            "origin": "AUTO",
            "measurePoint": {
                "id": "6"
            },
            "modifyDate": "2023-09-26T15:11:51.317",
            "noChrono": false
        },
        {
            "id": "18ad0e3e436-4e7",
            "variation": 5.0,
            "measure": 11005.0,
            "measuredAt": "2023-05-18T15:59:06.000",
            "correction": false,
            "repercussion": false,
            "origin": "AUTO",
            "measurePoint": {
                "id": "6"
            },
            "modifyDate": "2023-09-26T15:11:51.342",
            "noChrono": false
        }
    ]
}

11.2.3. Read readings

The /entities/v1/measurereading API lets you return meter readings in a GET query.

As described in chapter Listing, filtering and selecting, this search can be refined by filtering, sorting and selecting the attributes to be displayed.

For example:

Displays the "dateMeasure, measure, variation, description, origin" attributes of reading point readings with id "6", sorted by ascending reading date
https://carlsource.server.com/gmaoCS02/api/entities/v1/measurereading?filter[measurePoint.id]=6&sort=dateMeasure&fields=dateMeasure,measure,variation,description,origin
Key Value Description

filter[measurePoint.id]

6

Searches for meter readings for the reading point with the following id: 6

sort

dateMeasure

Sorts meter readings by ascending reading date

fields

dateMeasure,measure,variation,description,origin

Displays only the defined fields

Response obtained
{
    "data": [
        {
            "id": "4",
            "type": "measurereading",
            "links": {
                "self": "http://localhost:8380/xnet/api/entities/v1/measurereading/4"
            },
            "attributes": {
                "origin": 1,
                "description": null,
                "variation": 10000.0,
                "measure": 10000.0,
                "dateMeasure": "2007-12-10T00:00:00.000+01:00"
            }
        },
        {
            "id": "18ad0e3e436-442",
            "type": "measurereading",
            "links": {
                "self": "http://localhost:8380/xnet/api/entities/v1/measurereading/18ad0e3e436-442"
            },
            "attributes": {
                "origin": 2,
                "description": null,
                "variation": 0.0,
                "measure": 10000.0,
                "dateMeasure": "2023-04-17T15:07:06.000+02:00"
            }
        },
        {
            "id": "18ad0e3e436-4e6",
            "type": "measurereading",
            "links": {
                "self": "http://localhost:8380/xnet/api/entities/v1/measurereading/18ad0e3e436-4e6"
            },
            "attributes": {
                "origin": 2,
                "description": null,
                "variation": 1000.0,
                "measure": 11000.0,
                "dateMeasure": "2023-05-18T15:57:06.000+02:00"
            }
        },
        {
            "id": "18ad0e3e436-4e7",
            "type": "measurereading",
            "links": {
                "self": "http://localhost:8380/xnet/api/entities/v1/measurereading/18ad0e3e436-4e7"
            },
            "attributes": {
                "origin": 2,
                "description": null,
                "variation": 5.0,
                "measure": 11005.0,
                "dateMeasure": "2023-05-18T15:59:06.000+02:00"
            }
        }
    ],
    "links": {
        "self": "measurePoint.id=6&sort=dateMeasure&fields=dateMeasure%2Cmeasure%2Cvariation%2Cdescription%2Corigin"
    }
}

12. Managing Reservations with the API /reserves

The /reserves API allows you to manage one or more reservations (create, update, search, delete).

12.1. API Usage Rights

Using this API requires that the user under which the API is invoked has the appropriate profile permissions.
The API is governed by the profile rights: Work / Work Order and Stock / Reservations.

12.2. Create One or More Reservations

12.2.1. Create a Reservation

The /reserves/v1/add API allows you to submit a reservation using a POST request in JSON format (Media-Type: application/json).

Note

Creating a reservation is only possible if the work order is in the "Validated" status.

Creating a reservation is not allowed if the specified date is earlier than the work order’s start date.

If the specified reservation date is later than the work order’s end date, the end date will automatically be updated to match the reservation date.

Example of Content Sent in the POST Request Body
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
      "quantity": 1,
      "reserveDate" : "2024-01-05T09:12:55.835+01:00",
      "description" : "Test de création de réservation avec l’API REST",
        "item": {
            "code": "FILTRE-AIR-D20"
            }
        ,
        "wo": {
            "code": "DEV-WO-017-2006"
        },
        "actor": {
            "code": "DEMO"
        },
         "warehouse": {
            "code": "MAG2"
        }
    }’\
https://carlsource.server.com/gmaoCS02/api/reserves/v1/add

The corresponding fields for describing a reservation are as follows:

Field Type (Format or Length) Description Required / Optional

item

Alphanumeric

Code or ID of the item

Required

quantity

Numeric

Number of items to reserve

Required

warehouse

Alphanumeric

Code or ID of the warehouse for the reservation

Required

wo

Alphanumeric

Work order associated with the reservation

Required

reserveDate

Date

Reservation date

Optional. Defaults to current date.

actor

Alphanumeric

Code or ID of the actor

Optional. Defaults to connected actor.

description

Alphanumeric (60)

Description of the reservation

Optional

Response Received
HTTP/1.1 201 Created
{
    "data": {
        "id": "1917e380cdc-ac",
        "item": {
            "id": "FILTRE-AIR-D20",
            "code": "FILTRE-AIR-D20"
        },
        "quantity": 1.0,
        "reserveDate": "2024-01-05T09:12:55.835+01:00",
        "wo": {
            "id": "DEV17",
            "code": "DEV-WO-017-2006"
        },
        "actor": {
            "id": "14",
            "code": "DEMO"
        },
        "description": "Test de création de réservation avec l’API REST"
    }
}

12.2.2. Create a List of Reservations

The /reserves/v1/add-all API allows you to send a list of reservations using a POST request in JSON format (Media-Type: application/json).

Note

This list allows you to add reservations for one or more work orders, warehouses, or items. It is not mandatory to create the list with the same warehouse, item, or work order. Each reservation can contain data independent of the others.

If the API encounters a functional error (e.g., a required field is missing or an attempt is made to create a reservation for an invalid work order), the entire list is rejected.

Example of Content Sent in the POST Request Body
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
"data":[
        {
            "quantity": 1,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "description": "Test création de réservation 1",
            "item": {
                "code": "FILTRE-AIR-D20"
            },
            "wo": {
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "warehouse": {
                "code": "MAG2"
            }
        },
        {
            "quantity": 2,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "description": "Test création de réservation 2",
            "item": {
                "code": "FILTRE-AIR-D20"
            },
            "wo": {
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "warehouse": {
                "code": "MAG2"
            }
        },
         {
            "quantity": 3,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "description": "Test création de réservation 3",
            "item": {
                "code": "ITEM1"
            },
            "wo": {
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "warehouse": {
                "code": "MAG1"
            }
        }
    ]
}’\
Note

The fields to be filled in are the same as those of the /reserves/v1/add API.
The difference lies in:

  • the action to be called: add-all

  • and the format of the content: data enclosed in square brackets [ ].

Response Received
HTTP/1.1 201 Created
{
    "data": [
        {
            "id": "1917e380cdc-1eb",
            "item": {
                "id": "FILTRE-AIR-D20",
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 1.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV17",
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Test création de réservation 1"
        },
        {
            "id": "1917e380cdc-1ed",
            "item": {
                "id": "FILTRE-AIR-D20",
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV17",
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Test création de réservation 2"
        },
        {
            "id": "1917e380cdc-1ef",
            "item": {
                "id": "ITEM1",
                "code": "ITEM1"
            },
            "warehouse": {
                "id": "WAREHOUSE1",
                "code": "MAG1"
            },
            "quantity": 3.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV17",
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Test création de réservation 3"
        }
    ]
}

12.3. Update a Reservation

The /reserves/v1/update/<reserve-id> API allows you to update a reservation.

Example of content sent in the PATCH request body to update the warehouse and description of the reservation with ID '1917e380cdc-1eb'
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
      "data":  {
      "quantity": 1,
      "reserveDate" : "2024-01-05T09:12:55.835+01:00",
      "description" : "Réservation mise à jour par DEMO vers MAG1",
        "item": {
            "code": "FILTRE-AIR-D20"
        }
        ,
        "wo": {
            "code": "DEV-WO-017-2006"
        },
        "actor": {
            "code": "DEMO"
        },
         "warehouse": {
            "code": "MAG1"
        }
    }
} ‘ \
https://carlsource.server.com/gmaoCS02/api/reserves/v1/update/1917e380cdc-ac
Response Received
HTTP/1.1 200 OK
{
    "data": {
        "id": "1917e380cdc-ac",
        "item": {
            "id": "FILTRE-AIR-D20",
            "code": "FILTRE-AIR-D20"
        },
        "warehouse": {
            "id": "WAREHOUSE1",
            "code": "MAG1"
        },
        "quantity": 1.0,
        "reserveDate": "2024-01-05T09:12:55.835+01:00",
        "wo": {
            "id": "DEV17",
            "code": "DEV-WO-017-2006"
        },
        "actor": {
            "id": "14",
            "code": "DEMO"
        },
        "description": "Réservation mise à jour par DEMO vers MAG1"
    }
}

12.4. Update a List of Reservations

The /reserves/v1/update-all API allows you to update a list of reservations.

Note

In addition to the required attributes, it is necessary to provide the id of each reservation to be updated in the list.

Example of content sent in the PATCH request body
{
    "data": [
        {
            "id": "1917e380cdc-1eb",
            "item": {
                "code": "ITEM1"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 1"
        },
        {
            "id": "1917e380cdc-1ed",
            "item": {
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "code": "DEV-WO-018-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 2"
        },
        {
            "id": "1917e380cdc-1ef",
            "item": {
                "code": "ITEM1"
            },
            "warehouse": {
                "code": "MAG1"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 3"
        }
    ]
}
Response Received
{
    "data": [
        {
            "id": "1917e380cdc-1eb",
            "item": {
                "id": "FILTRE-AIR-D20",
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV17",
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 1"
        },
        {
            "id": "1917e380cdc-1ed",
            "item": {
                "id": "FILTRE-AIR-D20",
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV18",
                "code": "DEV-WO-018-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 2"
        },
        {
            "id": "1917e380cdc-1ef",
            "item": {
                "id": "ITEM1",
                "code": "ITEM1"
            },
            "warehouse": {
                "id": "WAREHOUSE1",
                "code": "MAG1"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV17",
                "code": "DEV-WO-017-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 3"
        }
    ]
}

12.5. Retrieve Reservations Linked to an Entity (Item, Work Order, or Warehouse)

The /reserves/v1/<entityType>/<entityId> API allows you to search for reservations linked to the entities wo, item, and warehouse.

Example of a GET request to search for reservations linked to the work order 'DEV-WO-018-2006'
https://carlsource.server.com/gmaoCS02/api/reserves/v1/wo/DEV18
Response Received
{
    "data": [
        {
            "id": "1917e380cdc-1ed",
            "item": {
                "id": "FILTRE-AIR-D20",
                "code": "FILTRE-AIR-D20"
            },
            "quantity": 2.0,
            "reserveDate": "2023-12-11T10:50:46.841+01:00",
            "wo": {
                "id": "DEV18",
                "code": "DEV-WO-018-2006"
            },
            "actor": {
                "id": "14",
                "code": "DEMO"
            },
            "description": "Mise à jour de la réservation 2"
        }
    ]
}
Search Entity Description

item

Item linked to the reservation

wo

Work order linked to the reservation

warehouse

Warehouse linked to the reservation

12.6. Delete a Reservation

The /reserves/v1/delete/<reserveId> API allows the deletion of a reservation.

Example of a DELETE request to remove the reservation with ID '1917e380cdc-1ed'
https://carlsource.server.com/gmaoCS02/api/reserves/v1/delete/1917e380cdc-1ed

13. Invoice Status Update Scenario: the /energy-meter-invoices API

13.1. API Usage Rights

Using this API requires that the user under which the API is invoked has the appropriate profile permissions.
The API is governed by the profile right: Equipment / Energy Billing Tracking.

13.2. Updating Invoice Statuses

The /energy-meter-invoices/v1/update-status API allows you to send a list of invoices to update using a POST request in JSON format (Media-Type: application/json).

Example of content sent in the POST request body
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
-d ' {
	"data":[
		{	"invoiceNumber" : "110",
			"status" : "PAID",
			"energyMeter" : {
						"id" : "nrj1" OU "code" : "ENERGY_01"
					}
		},
		{
			"invoiceNumber" : "111",
			"status" : "TOPAY",
			"energyMeter" : {
				"id" : "nrj1" OU "code" : "ENERGY_01"
			}
		}
	]
}' \
https://carlsource.server.com/gmaoCS02/api/energy-meter-invoice/v1/update-status

The corresponding fields for describing an invoice are as follows:

Field Type (Format or Length) Description Required / Optional

invoiceNumber

Alphanumeric

Invoice number

Required

status

Alphanumeric

Status

Required

The corresponding fields for describing an energy meter point are as follows:

Field Type (Format or Length) Description

code

Alphanumeric

Code of the energy meter point (leave empty if id is specified)

id

Alphanumeric

ID of the energy meter point (leave empty if code is specified)

Either code or id must be provided for the invoice to reference an energy meter point, but both attributes cannot be used simultaneously.

Response Received
HTTP/1.1 201 Created
{
"data":[
		{
            "invoiceNumber" : "110",
			"status" : "PAID",
			"energyMeter" : {
				"id" : "nrj1"
			}
		},
		{
			"invoiceNumber" : "111",
			"status" : "TOPAY",
			"energyMeter" : {
				"id" : "nrj1"
			}
		}
	]
}

The /link-equipments API allows you to add, move, modify, or close one or more links in the equipment hierarchy.

Using this API requires that the user under which the API is invoked has the appropriate profile permissions.
The API is governed by the profile right: Equipment / Equipment hierarchy.

  • If the link already exists and the end date is specified: right "Delete current link".

  • If the link already exists between the two pieces of equipment: right "Modify link information".

  • If the link exists for this junction: right "Modify link information".

Note

All these different link operations are handled by only two API endpoints:

  • /link-equipments/v1/add for managing a single link

  • /link-equipments/v1/add-all for managing a list of links

The use of attributes in the body of the API request determines whether it is a creation, move, modification, or closure of the link.

Usage examples:

  • Creation: If no link exists, specifying a parent, a child, and a start date creates the link in the hierarchy.

  • Move: Calling the same API with a different parent or child moves the link within the hierarchy.

  • Closure: Adding an end date closes the link in the hierarchy.

The /link-equipments/v1/add API allows you to submit a single hierarchy link using a POST request in JSON format (Media-Type: application/json).

Example of content sent in the POST request body
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
    "data": {
        "linkBegin":"2024-09-11T12:00:00",
        "description":"Lien API Rest",
        "ordering":1,
        "junction": {
            "id":"LOCATIONMATERIAL"
        },
        "parent": {
            "id":"ALLEMAGNE"
        },
        "child": {
            "code":"CEAU"
        }
    }
}' \
https://carlsource.server.com/gmaoCS02/api/link-equipments/v1/add

The corresponding fields for describing a hierarchy link are as follows:

Field Type (Format or Length) Description Required / Optional

linkBegin

Date

Start date of link validity

Required only for dated links

linkEnd

Date

End date of link validity

Optional

ordering

Numeric

Node ordering within a hierarchy branch

Optional

description

Alphanumeric

Description of the link

Optional

  • linkBegin: This field is required only if the child structure uses dated links.
    For example, a link between a structure node and an equipment requires a date, while a link between two structure nodes does not.

A link requires the use of the following reference entities:

Field Description Required / Optional

junction

Description of the link between structures

Required

parent

Parent equipment in the link

Optional

child

Child equipment in the link

Required

The corresponding fields for describing the reference entities of the link are as follows:

Field Type (Format or Length) Description

code

Alphanumeric (20)

Code of the reference entity

id

Alphanumeric (33)

ID of the reference entity

Warning

The use of either code or id is mandatory for a reference entity.

Response Received
HTTP/1.1 201 Created
{
    "data": [
        {
            "id": "19368f7c674-3",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "ALLEMAGNE",
                "code": "ALLEMAGNE"
            },
            "child": {
                "id": "9",
                "code": "CEAU"
            },
            "linkBegin": "2024-09-11T12:00:00.000",
            "linkEnd": "2200-12-31T01:00:00.000",
            "description": "lien API Rest",
            "ordering": 1
        }
    ]
}

The /link-equipments/v1/add-all API allows you to submit a list of hierarchy links using a POST request in JSON format (Media-Type: application/json).

Note

This list allows you to manage links across different pieces of equipment.
Links can be submitted in an unordered manner, as the processing will sort them based on the linkBegin attribute.

Example of content sent in the POST request body
curl -X POST -H "X-CS-Access-Token: your_access_token" -H "Content-Type: application/vnd.api+json" \
    -d '{
        "data": [
            {
            "junction": {
                "id":"LOCATIONMATERIAL"
            },
            "parent": {
                "id":"ALLEMAGNE"
            },
            "child": {
                "code":"BALL"
            },
            "linkBegin":"2024-09-11T12:00:00",
            "description":"Création du lien",
            "ordering":1
        },
        {
            "junction": {
                "id":"LOCATIONMATERIAL"
            },
            "parent": {
                "id":"FRANCE"
            },
            "child": {
                "code":"BALL"
            },
            "linkBegin":"2024-09-11T13:00:00",
            "description":"Déplacement du lien",
            "ordering":1
        },
        {
            "junction": {
                "id":"LOCATIONMATERIAL"
            },
            "parent": {
                "id":"FRANCE"
            },
            "child": {
                "code":"BALL"
            },
            "linkBegin":"2024-09-11T14:00:00",
            "description":"Modification de la date du lien existant",
            "ordering":1
        },
        {
            "junction": {
                "id":"LOCATIONMATERIAL"
            },
            "parent": {
                "id":"FRANCE"
            },
            "child": {
                "code":"BALL"
            },
            "linkBegin":"2024-09-11T15:00:00",
            "linkEnd":"2024-09-12T15:00:00",
            "description":"Clôture du lien",
            "ordering":1
        }
    ]
}' \
https://carlsource.server.com/gmaoCS02/api/link-equipments/v1/add-all

The above example illustrates the following scenarios:

  • Move of the link from parent "ALLEMAGNE" to parent "FRANCE" (see "Move of the link" in the code)

Warning

Moving a link results in closing the existing link and creating the new link in the hierarchy — see "Response Received" below.

  • Modification of the current link’s start date (see the first two occurrences of the linkBegin attribute)

  • Closure of the current link (see the occurrence of the linkEnd attribute)

Note

The fields to be filled in are identical to those of the /link-equipments/v1/add API.
The difference lies in the action to call (add-all) and the content format: data enclosed in square brackets [ ].

Response Received
HTTP/1.1 201 Created
{
    "data": [
        {
            "id": "19368f7c674-18",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "ALLEMAGNE",
                "code": "ALLEMAGNE"
            },
            "child": {
                "id": "2",
                "code": "BALL"
            },
            "linkBegin": "2024-09-11T12:00:00.000",
            "linkEnd": "2200-12-31T01:00:00.000",
            "description": "Création du lien",
            "ordering": 1
        },
        {
            "id": "19368f7c674-18",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "ALLEMAGNE",
                "code": "ALLEMAGNE"
            },
            "child": {
                "id": "2",
                "code": "BALL"
            },
            "linkBegin": "2024-09-11T12:00:00.000",
            "linkEnd": "2024-09-11T12:59:59.999",
            "description": "Création du lien",
            "ordering": 1
        },
        {
            "id": "19368f7c674-19",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "FRANCE",
                "code": "FRANCE"
            },
            "child": {
                "id": "2",
                "code": "BALL"
            },
            "linkBegin": "2024-09-11T13:00:00.000",
            "linkEnd": "2200-12-31T01:00:00.000",
            "description": "Déplacement du lien",
            "ordering": 1
        },
        {
            "id": "19368f7c674-19",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "FRANCE",
                "code": "FRANCE"
            },
            "child": {
                "id": "2",
                "code": "BALL"
            },
            "linkBegin": "2024-09-11T14:00:00.000",
            "linkEnd": "2200-12-31T01:00:00.000",
            "description": "Modification de la date du lien existant",
            "ordering": 1
        },
        {
            "id": "19368f7c674-19",
            "junction": {
                "id": "LOCATIONMATERIAL"
            },
            "parent": {
                "id": "FRANCE",
                "code": "FRANCE"
            },
            "child": {
                "id": "2",
                "code": "BALL"
            },
            "linkBegin": "2024-09-11T15:00:00.000",
            "linkEnd": "2024-09-12T15:00:00.000",
            "description": "Clôture du lien",
            "ordering": 1
        }
    ]
}

Analysis of the Response Received:

  • Creation: Response #1 corresponds to the creation of the link.

  • Move:

    • Response #2 corresponds to the closure of the link (same id) because moving a link closes the current link to create a new one.

    • Response #3 corresponds to the creation of the new link after the move request.

  • Modification: Response #4 corresponds to the modification of the current link.

  • Closure: Response #5 corresponds to the closure of the link in the hierarchy.

Warning

If an error occurs during API processing, no changes are applied.

The /entities/v1/linkequipment API allows you to retrieve equipment links using a GET request.

As described in the Listing, filtering and selecting chapter, this search can be refined using filters, sorting, and by selecting specific attributes to display.

Example
https://carlsource.server.com/gmaoCS02/api/entities/v1/linkequipment?filter[child.code]=BALL&sort=linkBegin

15. Inventory handling scenario: the /inventories API

The /inventories API allows the creation of one or more inventories.

15.1. API usage rights

Using the API requires that the user has the necessary profile rights. The API is controlled by the inventory creation right: Stock/Inventory.

15.2. Create one or more inventories

15.2.1. Create one inventory

The /inventories/v1/add API allows sending, in a POST request in JSON format (Media-Type: application/json), an inventory movement.

Example
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
	"movementQuantity": 11.0,
	"description": "Test de création d’inventaire avec l’API REST",
	"item": {
		"code": "ITEM1"
		},
	"location": {
		"code": "A1C10"
		},
	"actor": {
		"code": "DEMO"
		},
	"warehouse": {
		"code": "MAG1"}
		}
	}'https://carlsource.server.com/gmaoCS02/api/inventories/v1/add

The corresponding fields for the description of an inventory are as follows:

Fields Type (Format or Length) Description Mandatory / Optional

item

Alphanumeric

Code or id of the item

Mandatory

movementQuantity

Numeric

Quantity inventoried

Mandatory

warehouse

Alphanumeric

Code or id of the reservation warehouse

Mandatory. May be optional if the item has already been inventoried in only one warehouse.

location

Alphanumeric

Work order carrying the reservation

Optional

movementDate

Date

Inventory date

Optional. Current date by default.

actor

Alphanumeric

Code or id of the actor

Optional. Connected actor by default.

description

Alphanumeric

Inventory description

Optional

materialMoved

Alphanumeric

Code or id of the equipment

Mandatory for the inventory of a serialized item

batchNum

Alphanumeric

Associated batch number

Optional

movementType

Alphanumeric

Code or id of the movement type

Optional. Default movement type: Inventory.

inventoryId

Alphanumeric

Inventory slip

Optional

Response obtained
HTTP/1.1 201 Created
{
   "data":{
		"id":"19759fe5d1c-1",
		"actor":{
			"id":"14",
			"code":"DEMO"
		},
		"item":{
			"id":"ITEM1",
			"code":"ITEM1"
		},
		"movementQuantity":11.0,
		"movementDate":"2025-06-10T15:21:58.311+02:00",
		"location":{
			"id":"LOCATION1",
			"code":"A1C10"
	},
		"warehouse":{
			"id":"WAREHOUSE1",
			"code":"MAG1"
			},
		"description":"Test de création d’inventaire avec l’API REST",
            "movementType":{
			   "id":"INVENTORY",
			   "code":"INVENTAIRE"}
	}
}

15.2.2. Create an inventory list

The API/inventories/v1/add-all allows sending, in a POST request in JSON format (Media-Type: application/json), a list of inventories.

Note

If the API encounters a functional error, such as a missing mandatory field, the entire list is rejected.

Example of content sent in the POST request body
curl -X POST -H "X-CS-Access-Token: votre_access_token" -H "Content-Type: application/vnd.api+json" \
    -d    '{
    "data": [
    {
        "movementQuantity": 4.0,
        "description": "Test de création de plusieurs inventaires avec l’API REST. Inventaire 1",
        "item": {
            "code": "ITEM1"
        },
        "location": {
            "code": "A1C10"
        },
        "actor": {
            "code": "DEMO"
        },
        "warehouse": {
            "code": "MAG1"
        }
    },
    {
        "movementQuantity": 3.0,
        "description": "Test de création de plusieurs inventaires avec l’API REST. Inventaire 2",
        "item": {
            "code": "ITEM1"
        },
        "location": {
            "code": "A2C03"
        },
        "actor": {
            "code": "DEMO"
        },
        "warehouse": {
            "code": "MAG2"
        }
    }
    ]
}’\https://carlsource.server.com/gmaoCS02/api/inventories/v1/add-all
Note

The fields to be filled in are identical to those of the inventories/v1/add API.
The difference lies in the action to be called add-all, and in the content formatting:
data enclosed in brackets [ … ].

Response obtained
HTTP/1.1 201 Created
{
    "data": [
    {
        "id": "19759fe5d1c-57",
        "actor": {
            "id": "14",
        "code": "DEMO"
        },
        "item": {
            "id": "ITEM1",
            "code": "ITEM1"
        },
        "movementQuantity": 4.0,
        "movementDate": "2025-06-10T15:42:02.225+02:00",
        "location": {
            "id": "LOCATION1",
            "code": "A1C10"
        },
        "warehouse": {
            "id": "WAREHOUSE1",
            "code": "MAG1"
        },
        "description": "Test for creating multiple inventories with the REST API. Inventory 1",
        "movementType": {
            "id": "INVENTORY",
            "code": "INVENTORY"
        }
    },
    {
        "id": "19759fe5d1c-5a",
        "actor": {
            "id": "14",
            "code": "DEMO"
        },
        "item": {
            "id": "ITEM1",
            "code": "ITEM1"
        },
        "movementQuantity": 3.0,
        "movementDate": "2025-06-10T15:42:02.292+02:00",
        "location": {
            "id": "LOCATION4",
            "code": "A2C03"
        },
        "warehouse": {
            "id": "WAREHOUSE2",
            "code": "MAG2"
        },
        "description": "Test for creating multiple inventories with the REST API. Inventory 2",
        "movementType": {
            "id": "INVENTORY",
            "code": "INVENTORY"
        }
    }
    ]
}

16. Importing external invoices: the /invoices API

16.1. Overview

This REST API allows you to import external invoices into CARL Source, in accordance with the EN16931 standard and the specific requirements of the information system. It is intended for clients who wish to automate the integration of their electronic invoices (e-invoices) into CARL Source.

16.1.1. Importing invoicing data

  • Endpoint: /api/invoices/v1/add

  • HTTP Method: POST

  • Expected content type (Content-type): application/json

  • Authentication: Required

16.1.2. Import invoicing data and the file containing the invoice

  • Endpoint: /api/invoices/v1/add

  • HTTP Method: POST

  • Expected content type (Content-type): multipart/form-data

  • Authentication: Required

16.1.3. Licensing Terms

Access rights to the APIs are determined by the following module settings (System Menu, Module Settings feature):

  • Purchasing / INVOICE_IMPORT_ENABLED | Enable e-invoice import: must be checked

  • Purchasing / INVOICE_IMPORT_FORMAT | E-invoice import format: must be set to "CARL Source"

As well as by the following user profiles:

  • Purchasing / Invoices / Enable invoice creation via e-invoice import API: must be checked

16.2. How the API Works

16.2.1. Processing Steps

  1. Data validation:

    • Required fields are filled in (see below).

    • The invoice type is validated (certain types, such as 384/CORRECTED or 389/SELF_BILLED, are not currently supported).

    • Business rules ensuring the consistency of the data provided (PO, currency, etc.) are enforced.

  2. Import Process:

    • If the invoice does not exist, it is created.

    • If it exists and is still in the "In Development" status, it is updated.

    • If the associated PO cannot be found, “pre-invoice” mode must be enabled so that the invoice can still be created as a “pre-invoice” (draft).

    • If the reference invoice cannot be found, “pre-invoice” mode must be enabled so that the credit memo can still be created as a “pre-credit memo” (draft).

16.2.2. Return Codes

  • 200: Import successful

  • 400: Invalid input parameters

  • 403: Insufficient permissions

  • 500: Internal error

16.3. Expected Data Structure

16.3.1. Example of a JSON payload

{
  "data": {
    "invoiceNumber": "FAC-2026-001",
    "invoiceIssueDate": "2026-04-17T10:00:00+02:00",
    "invoiceTypeCode": "380",
    "invoiceStatus": "PENDING",
    "buyerReference": "ACH-12345",
    "purchaseOrderReference": "PO-2026-001",
    "deliveryCode": "BL-2026-001",
    "precedingInvoiceReference": null,
    "sellerReference": "VEND-98765",
    "supplierReference": "FOUR-54321",
    "invoiceReference": "REF-2026-001",
    "invoiceCurrencyCode": "EUR",
    "invoiceTotalAmountWithVAT": 1200.50,
    "invoiceTotalVATAmount": 200.08,
    "invoiceTotalAmountWithoutVAT": 1000.42
  }
}

16.3.2. Name of the Main Fields

Field Required Name

invoiceNumber

Yes (1)

Unique external invoice number

invoiceIssueDate

Yes

Invoice issue date (ISO 8601 format)

invoiceTypeCode

No (2)

Invoice type code (380, 381, 384, 389)

invoiceStatus

Yes

Internal status of the invoice in the calling system

buyerReference

No

Buyer References

purchaseOrderReference

No (3)

Reference of the associated PO

deliveryCode

No (3)

Client waybill number (required if waybill mode is enabled)

precedingInvoiceReference

No

Original invoice reference (required for 381)

sellerReference

No

Seller Reference

supplierReference

No

Supplier Reference

invoiceReference

No

Reference number of the original invoice for credit memos

invoiceCurrencyCode

Yes

Currency code (ISO 4217 format)

invoiceTotalAmountWithVAT

Yes

Total amount including tax

invoiceTotalVATAmount

Yes

Total VAT Amount

invoiceTotalAmountWithoutVAT

Yes

Total amount excluding VAT

(1) Mandatory or optional depending on the business context (pre-invoicing possible)

(2) Required for certain business rules (e.g., 381 with precedingInvoiceReference)

(3) Whether this is required depends on the invoicing method (PO or delivery note—currently POs only)

16.4. Points to Note

  • Invoice Type:

    • Invoices of type 384 (Corrective) are not taken into account.

    • Invoices of type 389 (Self-invoicing) are currently rejected by the API.

  • Preliminary Invoice:

    • If no PO is found, “pre-invoice” mode must be enabled in the settings for the invoice to be imported. Otherwise, the invoice will not be imported.

16.5. Best Practices

  • Always fill in the required fields.

  • Verify the configuration of the Purchasing module and the profile of the user calling the API on the CARL Source side.

  • Use the correct invoice type codes according to the EN16931 standard. If the type is not specified, the system uses type 380—commercial invoice—by default.

  • If an error occurs, view the message returned in the body of the HTTP response, as well as the server-side CARL Source application logs.

  • During the implementation phase, it may be convenient to use BASIC authentication to run tests.
    However, we strongly encourage the use of OAuth2 tokens for the transition to production.

16.6. Example of a curl request

Here is an example of an API call to import external invoices using curl. Please note: CARL Source SaaS environments are protected and—for security reasons—reject requests that do not specify a user-agent or specify a user-agent containing "curl."

  1. Example of importing invoicing data

curl -X POST \
  pass:[https://][red]#carlsource.server.com/gmaoCS02#/api/invoices/v1/add \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer [red]#your_access_token#" \
  --user-agent "Mozilla/5.0" \
  --data-binary @- <<'EOF'
{
  "data": {
    "invoiceNumber": "FAC-2026-001",
    "invoiceIssueDate": "2026-04-17T10:00:00+02:00",
    "invoiceTypeCode": "380",
    "invoiceStatus": "PENDING",
    "buyerReference": "ACH-12345",
    "purchaseOrderReference": "PO-2026-001",
    "deliveryCode": "BL-2026-001",
    "precedingInvoiceReference": null,
    "sellerReference": "VEND-98765",
    "supplierReference": "FOUR-54321",
    "invoiceReference": "REF-2026-001",
    "invoiceCurrencyCode": "EUR",
    "invoiceTotalAmountWithVAT": 1200.50,
    "invoiceTotalVATAmount": 200.08,
    "invoiceTotalAmountWithoutVAT": 1000.42
  }
}
EOF
  • Replace the value in red carlsource.server.com/gmaoCS02 with the URL and context of your CARL Source instance.

  • Replace your_access_token with a valid authentication token.

  • Note: To simplify testing, you can replace -H "Authorization: Bearer your_access_token" \ with -u username:password using a valid username and password combination.

16.6.1. Example with PDF file upload (multipart/form-data)

Here is an example of a call to the API for importing external invoices with an attached PDF file, using curl:

  1. Example with PDF file upload (multipart/form-data)

DTO=$(cat <<'EOF'
{
  "data": {
    "invoiceNumber": "FAC-2026-001",
    "invoiceIssueDate": "2026-04-17T10:00:00+02:00",
    "invoiceTypeCode": "380",
    "invoiceStatus": "PENDING",
    "buyerReference": "ACH-12345",
    "purchaseOrderReference": "PO-2026-001",
    "deliveryCode": "BL-2026-001",
    "precedingInvoiceReference": null,
    "sellerReference": "VEND-98765",
    "supplierReference": "FOUR-54321",
    "invoiceReference": "REF-2026-001",
    "invoiceCurrencyCode": "EUR",
    "invoiceTotalAmountWithVAT": 1200.50,
    "invoiceTotalVATAmount": 200.08,
    "invoiceTotalAmountWithoutVAT": 1000.42
  }
}
EOF
)

curl -X POST \
  pass:[https://][red]#carlsource.server.com/gmaoCS02#/api/invoices/v1/add \
  -H "Authorization: Bearer [red]#your_access_token#" \
  --user-agent "Mozilla/5.0" \
  -F "dto=$DTO;type=application/json" \
  -F 'pdf=@[red]#/path/to/invoice.pdf#;type=application/pdf'
  • The dto section must be sent with the content type application/json.

  • The pdf section corresponds to the PDF file to be attached (parameter required = false: submitting the PDF is optional).

  • Replace the value in red carlsource.server.com/gmaoCS02 with the URL and context of your CARL Source instance.

  • Replace your_access_token with a valid authentication token.

  • Replace /path/to/invoice.pdf with the local path to your PDF file.

17. Data Exchange

17.1. Usage Rights

Access rights to the APIs are governed by the following profile permissions:

  • Data Exchange / Exchange Interface / Import: for APIs starting with "api/exchange/v1/import/"

  • Data Exchange / Exchange Interface / Export: for APIs starting with "api/exchange/v1/export/"

  • Data Exchange / Exchange History / Read: for the API "api/exchange/v1/executions/"

17.2. Synchronous Export

This API allows you to export data through an interface in synchronous mode. The result corresponds to the content of the generated file.

  • Signature: api/exchange/v1/export/synchronous/interface/<interface code>

  • HTTP Method: POST

  • Message Body (optional) in JSON format with the following properties:

Property Required Definition

customFilterCode

No

Code of the custom filter

evalParameters

No

JSON object containing the list of attribute codes to filter on, along with their corresponding filter expressions.
Example: {"xtraTxt01": "texte", "xtraNum01": 20} to retrieve entities where attribute “xtraTxt01” equals "texte" and attribute “xtraNum01” equals 20.

Example of message body:

{
  "customFilterCode": "WO_02",
  "evalParameters": {
    "code": "CTRL*"
  }
}

Example of using the API via cURL:

Execution of the 'USER_OUT' interface, writing the result to the file "user_out.xml"
curl -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/export/synchronous/interface/USER_OUT \
     -u identifiant:mot_de_passe \
     -o user_out.xml
Use of a filter to export users whose code ends with "MO":
curl -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/export/synchronous/interface/USER_OUT \
     -u identifiant:mot_de_passe \
     -H 'Content-Type: application/json' \
     -d '{"evalParameters": {"code": "*MO"}}' \
     -o user_out_filtered.xml

17.3. Asynchronous Export

This API allows you to perform a data export via an interface and/or an external system in asynchronous mode.

  • Signatures:

    • Export via an interface: api/exchange/v1/export/asynchronous/interface/<interface code>

    • Export via an external system: api/exchange/v1/export/asynchronous/external-system/<external system code>

    • Export via an interface in an external system: api/exchange/v1/export/asynchronous/external-system/<external system code>/interface/<interface code>

  • HTTP Method: POST

  • Message Body (optional) in JSON format: see the message body in chapter Synchronous Export

  • Response in JSON format, encapsulated in the data property:

Property Required Definition

messageId

Yes

Exchange history identifier (see Monitoring Asynchronous Exchanges)

Example of using the API via cURL:

Execution of the 'USER_OUT' interface (option '-s' used to display only the response content):
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/export/asynchronous/interface/USER_OUT \
     -H "X-CS-Access-Token: your_access_token"
Response Received :
{"data":{"messageId":"0217d44f-c142-46a8-ae17-dd07b04289cf"}}
Execution of the 'USER_OUT' interface in the external system 'EXT_SYST_XML' using a filter to export users whose code ends with "MO":
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/export/asynchronous/external-system/EXT_SYST_XML/interface/USER_OUT \
     -u identifiant:mot_de_passe \
     -H 'Content-Type: application/json' \
     -d '{"evalParameters": {"code": "*MO"}}'
Response Received :
{"data":{"messageId":"aa72e3dd-00eb-4559-b183-81afead5056e"}}

17.4. Synchronous Import

This API allows you to perform a data import via an interface and/or an external system in synchronous mode.

  • Signatures:

    • Import via an interface: api/exchange/v1/import/synchronous/interface/<interface code>

    • Import via an external system: api/exchange/v1/import/synchronous/external-system/<external system code>

    • Import via an interface in an external system: api/exchange/v1/import/synchronous/external-system/<external system code>/interface/<interface code>

  • HTTP Method: POST

  • Message Body (optional when using an external system): content of the data exchange to be imported

  • Response in JSON format, encapsulated in the data property:

Property Required Definition

status

Yes

Boolean value true or false indicating the success or failure of the import

errors

Yes

List of errors returned during the import

Response examples:

Successful import:
{
    "data": {
        "status": true,
        "errors": []
    }
}
Import with errors:
{
    "data": {
        "status": false,
        "errors": [
            "Erreur lors de la validation (costCenter):org.postgresql.util.PSQLException: ERREUR: valeur trop longue pour le type character varying(60) Sur l’élément principal numéro 2 de tag 'costCenter' [srcPos='2' code='SUIVI-PLOMB']\n"
        ]
    }
}

Example of using the API via cURL:

Execution of the 'COSTCENTER_IN_CSV' interface by providing the file "costcenter_in.csv":
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/import/synchronous/interface/COSTCENTER_IN_CSV \
     -H "X-CS-Access-Token: your_access_token" \
     -d @costcenter_in.csv
Response Received :
{"data":{"status":true,"errors":[]}}
Execution of the 'COSTCENTER_IN_CSV' interface in the external system 'EXT_SYST_XML':
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/import/synchronous/external-system/EXT_SYS_XML/interface/COSTCENTER_IN_CSV \
     -H "X-CS-Access-Token: your_access_token" \
Response Received :
{"data":{"status":true,"errors":[]}}

17.5. Asynchronous Import

This API allows you to perform a data import via an interface and/or an external system in asynchronous mode.

  • Signatures:

    • Import via an interface: api/exchange/v1/import/asynchronous/interface/<interface code>

    • Import via an external system: api/exchange/v1/import/asynchronous/external-system/<external system code>

    • Import via an interface in an external system: api/exchange/v1/export/asynchronous/external-system/<external system code>/interface/<interface code>

  • HTTP Method: POST

  • Message Body (optional when using an external system): content of the data to be imported

  • Response in JSON format, encapsulated in the data property:

Property Required Definition

messageId

Yes

Identifier of the exchange history (see Monitoring Asynchronous Exchanges)

Example of using the API via cURL:

Execution of the 'COSTCENTER_IN_CSV' interface by providing the file "costcenter_in.csv":
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/import/asynchronous/interface/COSTCENTER_IN_CSV \
     -H "X-CS-Access-Token: your_access_token" \
     -d @costcenter_in.csv
Response Received :
{"data":{"messageId":"f2a666e0-70b4-4d26-bf4d-9d950c3cb27b"}}
Execution of the 'COSTCENTER_IN_CSV' interface in the external system 'EXT_SYST_XML':
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/import/asynchronous/external-system/EXT_SYS_XML/interface/COSTCENTER_IN_CSV \
     -H "X-CS-Access-Token: your_access_token" \
Response Received :
{"data":{"messageId":"ed122f53-85b0-4303-9f27-2a9b0741ea17"}}

17.6. Monitoring Asynchronous Exchanges

This API allows you to check the status of an asynchronous exchange.

  • Signature: api/exchange/v1/executions/<messageId>

  • HTTP Method: GET

  • Response in JSON format, encapsulated in the data property:

Property Definition

messageId

Identifier corresponding to the triggered exchange (included in the response from asynchronous APIs)

execStatus

Execution result code (see value list 'EXCHANGESTATUS')

processStep

Current step of the exchange

processedElements

Number of elements processed

errorCode

Error code for the data exchange (see value list 'EXCHANGEERROR')

rejectedElements

Number of elements rejected

id

Exchange history identifier

links

JSON object containing a link (self property) to the detailed view of the exchange history

Example of response:
{
    "data": {
        "messageId": "ed122f53-85b0-4303-9f27-2a9b0741ea17",
        "processStep": "IMPORTATION",
        "execStatus": "OK",
        "processedElements": 1,
        "rejectedElements": 0,
        "id": "19324b43129-53a",
        "links": {
            "self": "https://carlsource.server.com/gmaoCS02/api/entities/v1/interfaceexecution/19324b43129-53a"
        }
    }
}

Example of using the API via cURL:

Request to monitor an exchange execution with identifier "4ddd58d5-8a24-4541-ba15-facddefcb07b" during which an error occurred:
curl -s -X POST https://carlsource.server.com/gmaoCS02/api/exchange/v1/executions/4ddd58d5-8a24-4541-ba15-facddefcb07b \
     -H "X-CS-Access-Token: your_access_token" \
Response Received :
{
    "data":{
        "messageId":"4ddd58d5-8a24-4541-ba15-facddefcb07b",
        "processStep":"UPLOAD",
        "execStatus":"WARNING",
        "processedElements":0,
        "rejectedElements":0,
        "errorCode":"TECH001",
        "id":"19324b43129-66a",
        "links":{
            "self":"https://carlsource.server.com/gmaoCS02/api/entities/v1/interfaceexecution/19324b43129-66a"
         }
    }
}

18. Conclusion

You now have the necessary information to get started with this API and interact with CARL Source objects:

  • authenticate,

  • list, create, read, update and delete business objects,

  • move these objects through their life cycle via workflow-transitions.

 


Trademark notice

Every effort has been made to ensure the accuracy of the information at the time of publication of this document.
As CARL Source is constantly evolving, CARL Berger-Levrault cannot be held responsible for any gaps or errors in this document.
If you notice any inconsistencies or errors, please contact CARL Berger-Levrault’s support department.
 
Any reproduction, in whole or in part, in any form whatsoever, is strictly prohibited without the prior authorization of CARL Berger-Levrault.
 
All trademarks and product names mentioned in this document are the property of their respective owners as listed below:

  • Android™ and Google Chrome® are registered trademarks of Google LCC.

  • ArcGIS® is a registered trademark of the Environmental Systems Research Institute.

  • Elasticsearch® is a registered trademark of Elasticsearch B.V. in the United States and other countries.

  • Firefox® is a registered trademark of the Mozilla Foundation.

  • Java™ and Oracle® are registered trademarks of Oracle Corporation.

  • PostgreSQL® is a registered trademark of The PostgreSQL Community Association of Canada.

  • Safari® is a trademark of Apple Inc. registered in the U.S. and other countries.

  • Azure®, SQL Server®, Microsoft Edge® and Windows® are registered trademarks of Microsoft Corporation.

  • Tomcat® is a registered trademark of the Apache Software Foundation in the United States and other countries.