Obtaining the list of available versions
To get a list of all released FM RESTful API version, perform a HTTP GET request to the versions resource
1
2 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]"
-H "X-FM-Signature: [Message_Signature]" [FM_ENDPOINT]/api/versions |
This call will return a list with the following format:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | [
{
"Id": 1,
"Description": "v1",
"LastVersion": false
},
{
"Id": 2,
"Description": "v2",
"LastVersion": false
},
...
{
"Id": N,
"Description": "vN",
"LastVersion": true
}
] |
Id is the number to be set in the request header X-FM-API-Version and LastVersion tells which one was the last, public released version. Please follow the section ForceManager API Versions for more information about consuming a specific FM RESTful API version.
Creating Records
To insert a new record use the HTTP POST method for the entity and include the data in the request body as a JSON object.
1 | curl -H "Accept: application/json" -H "Content-Type: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]" -X POST d@[file_route] [FM_ENDPOINT]/api/[entity] |
Where [file_route] is a text file containing the object’s data; in this case, should be in json format (as specified on the Content-Type header), for example:
1
2
3
4
5
6
7
8
9
10 | {
"field_1": "Value field 1",
"field_2": "",
...
"field_n": "Value field n",
"z_field_1": "Value Z field 1",
"z_field_2": "Value Z field 2",
...
"z_field_m": "Value Z field m"
} |
You would notice in the previous example, standard fields (on blue) and extra fields (on green, refer to this section for more information).
Please, refer to the section Data transfer for more information. The next table shows the possible responses when creating records on the FM System:
Response Code | Meaning | Body |
201 | The entity was created successful | Status message with the Entity’s id. |
400 | The request is bad formed, probably the input file is in an invalid format. | Status message with the validation errors. |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Updating Records
To update an existing record use the HTTP PUT method for the entity, include the data in the request body as a JSON object and specify the entity’s identifier.
1 | curl -H "Accept: application/json" -H "Content-Type: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]" -X PUT d@[file_route] [FM_ENDPOINT]/api/[entity]/[entity_id] |
Where [file_route] is a text file containing the object’s data, [entity_id] is the id of the entity on the FM System.
It’s important to notice that when updating records, if an entity field is present on the request body and is blank, this field will be set to null on the FM System. If you want to leave a field intact, you must not include it on the request.
The next table shows the possible responses when updating records on the FM System:
Response Code | Meaning | Body |
200 | The entity was updated successful | Short status message |
304 | The entity wasn’t updated, probably doesn’t exist on the FM System. | No body |
400 | The request is badly formed, probably the input file is in an invalid format. | Status message with the validation errors |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Deleting Records
To delete an existing record use the HTTP DELETE method for the entity, you must specify the entity’s identifier.
1 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]" -X DELETE [FM_ENDPOINT]/api/[entity]/[entity_id] |
Where [entity_id] is the id of the entity on the FM System.
The next table shows the possible responses when updating records on the FM System:
Response Code | Meaning | Body |
200 | The entity was deleted successful | Short status message |
400 | The request is badly formed, probably the id is not a valid positive integer. | Status message with the validation errors |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Searching for Records
To search for a list of records, you must send a HTTP GET method to the specific entity’s resource. All entities implement at least two search types:
Search all entities.
Search by entity’s id/type.
However some implement more search methods:
Search by important fields.
Advanced Search.
Before digging into search, it’s important to have a look on the FM RESTful API pagination.
Search Pagination
Pagination is the process of dividing the content (a list of items) on several discrete chunks (pages), to know more about this topic, you can navigate to this site.
The pagination in FM System is controlled using HTTP headers on the request/response:
Header | Description | Direction |
X-FM-Page | Indicates the current page on the result list, but it also is used, when sent on a request, to specify which page to receive. When not sent by the client, the system assumes X-FM-Page= 0 | Both |
X-FM-Prev-Page | The previous page on the list | FM API -> Client |
X-FM-Next-Page | The next page on the list | FM API -> Client |
X-FM-Entity-Count | The number of records on the current page | FM API -> Client |
The current version of the RESTful API has a fixed value for the number of returned records on each page (pagesize) set on 500 items, except while downloading master data (see section Search List of Values) which has a fixed pagesize of 5000 records. The received/sent pages on the API are zero (0) index based.
For iterating over the list of items trough a set of pages, the most common procedure is to set the headerX-FM-Page = 0, and then perform the first request. Then, the system returns the header X-FM-Next-Page = 1, next, after that, the client sends the same request but with X-FM-Next-Page = 1, and so on.
At some point during the request with page n-1, the client will send the request with X-FM-Next_oage = n and receive an empty list of items on the response body, this means there is no more data for this query.
IMPORTANT: To know when there isn’t any more data available on the paginated list, the response body comes with an empty list. This is also valid when sending a X-FM-Next-Page > n
To illustrate this concept, there is the example in this section: Pagination.
All search types on the API are paginated except the Search by entity id:
Search type | Is paginated |
Search all entities | Yes |
Search by entity’s id/type | No |
Search by important fields | Yes |
Advanced Search | Yes |
Search List of Values | Yes |
Search Internal Ids | Yes |
Search all entities
To obtain all the entities of a certain kind (always paginated), you should perform an HTTP GET method to the specific entity’s resource without any parameters.
1 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Page: 0" -H "X-FM-Signature: [Message_Signature]" [FM_ENDPOINT]/api/[entity] |
You may notice the “X-FM-Page: 0” on the request, which is optional for the first page, but to iterate over the list, the following requests should be performed with “X-FM-Page: X-FM-Next-Page from previous response”.
The next table shows the possible responses to this action:
Response Code | Meaning | Body |
200 | List obtained successful | The list of entities which can have a length of zero or one items. |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Search by entity id
To get an entity data by its id you should perform a HTTP GET method to the specific entity’s resource passing the entity’s id on the URL.
1 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]" [FM_ENDPOINT]/api/[entity]/[entity_id] |
The next table shows the possible responses to this action:
Response Code | Meaning | Body |
200 | List obtained successful | The list of entities which can have a length of zero or one items. |
400 | The request is badly formed, probably the id is negative | Status message with the validation errors |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Search by important fields
Most of the entities define important fields, which are those relevant for searching. You should address toEntity Types for getting the important field list for every entity. The general call for this functionality is:
1 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]” [FM_ENDPOINT]/api/[entity]?important_field_name_1=important_field_value_1& important_field_name_2=important_field_value_2& ….. & important_field_name_n=important_field_value_n |
All important fields sent with the request will be joined with logical AND operators in a LIKE fashion. I.E.: They are mutually exclusionary. For example, searching contacts passing the fields on the request:first_name = ‘Charles’, postcode=’09161’ will transform the query to: name LIKE ‘%Charles%’ AND postcode LIKE ‘%09161%’.
To perform this kind of query, we will use an example: We will search Contacts; so we can go to the referred documentation and notice that for contacts, and find some of the important fields: first_name, last_name, postcode, province_name, email, etc…
Then for example, to search all Contacts with name “Dani” we should perform:
1
2
3 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]"
-H "X-FM-Signature: [Message_Signature]” [FM_ENDPOINT]/api/contacts?first_name=Dani |
Then, the API will return a paginated list of values, as the first_name is a LIKE operator, it could return some of them with the first_name Dani as part of it. E.G.: Daniel, Danica, Svendanik, etc…
To search for the same first_name but within a gmail email account:
1
2
3 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]"
-H "X-FM-Signature: [Message_Signature]” [FM_ENDPOINT]/api/contacts?first_name=Dani&mail=gmail.com |
Again, the mail important field is transformed to mail LIKE ‘%gmail.com%’.
The next table shows the possible responses to this action:
Response Code | Meaning | Body |
200 | List obtained successfully | The list of entities which can have a length of zero or one items. |
400 | The request is badly formed, probably fields are incorrectly informed. | Status message with the validation errors |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Advanced Search
If the important field search is not enough, the FM RESTful API provides a SQL similar advanced search option. To run this process, the general call is
1 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]” [FM_ENDPOINT]/api/[entity]?q=[FM query syntax] |
Where [FM query syntax] is a subset of the SQL language used to query DBs, it allows only the use of the WHERE and the ORDER BY expressions. It is defined on the Annex II: ForceManager Query Language.
It’s important to highlight that a search can be performed by any field present on the entity, even using the extra fields.
Searching Identifiers
In several cases, it’s required to obtain the internal FM ids to perform certain operations, this is quite evident when performing inserts or updates on the system. For example, you will need to inform the activity_type_idfield when creating an activity (in fact, it’s mandatory, so you need to specify a valid value).
In FM RESTful API there are two methods to perform this operation:
Search List of Values.
Search by Internal Ids.
Search List of Values
This is used to get a paginated list of master records of a specific type (a table on ForceManager System), there are two methods to read this resource:
Obtaining the List of Available Resources.
Searching List of Values by Resource Name.
Obtaining the List of Available Resources
With this call, you can get all the resources which are available to get data from. You should perform an HTTP GET method to the values/info resource without any parameter:
1 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]" [FM_ENDPOINT]/api/values/info |
Then, the system will return a list with the name and description of each available master table. The name is the variable you must use to download master tables data using Search List of Values by Resource Name.
The next table shows the possible responses to the action:
Response Code | Meaning | Body |
200 | List obtained successfully | The list of available resources. |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Search List of Values by Resource Name
In this case, the records of any table with a specific format can be obtained, to call this method, you should perform an HTTP GET to the values resource with a resourceName parameter and an optional advanced search parameter (See section Advanced Search for more information).
The resourceName is the name of the table you need to get records for and can be queried by Obtaining the List of Available Resources.
Only records from tables with these fields are obtainable with this metod:
1 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]" [FM_ENDPOINT]/api/values?resourcename=[Table Name]&q=[FM query syntax] |
Field | Description |
id | The primary of the table |
description_es | The main name/code of the record |
deleted | Is the record is deleted?: 1 -> True; 0 -> False |
id[Name] | It's a foreign key, with this format the API is able to recognize it as a reference to another table. The [Name] value on the Field means any valid SQL variable, like: idContract, id_Person, etc… |
The next table shows the possible responses to the action:
Response Code | Meaning | Body |
200 | List obtained successful | The list of values. |
400 | The request is badly formed, probably the input is incorrect. | Status message with the errors |
404 | The system was unable to find the object list | Short status message |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Important: The default constraint of 500 records per page on all paginated searches was extended in this method to 5000.
Search by Internal Ids
This is used to get in a single call the list of records on the FM System that match an Id on your system. The FM’s id is called internal id and the id on your system is the external id or ext_id. For example, to get a sales representative id, you must call this action passing the externalId on your CRM/ERP/etc…
In the section Internal Ids, you can see the full list of resources available. You should perform an HTTP GET method to the internalid resource with a type and externalId parameters:
1 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]" [FM_ENDPOINT]/api/internalid?type=[Resource Type]&externalid=[external_id] |
Where [Resource Type] is one of the resources defined in the section Internal Ids and [external_id] is the id on your system.
The next table shows the possible responses to the action:
Response Code | Meaning | Body |
200 | List obtained successful | The list of internal ids. |
400 | The request is badly formed, probably some input field has been filled incorrectly. | Status message with the errors |
404 | The system was unable to find the object for the informed externalId and Resource Type | Short status message |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Performing operations on Lists of Values
The System allows you to operate the List of Values, this resource is a bit different from others, and as such, we’ll explain the procedure to execute such actions.
The FM RESTful API only allows the following to work (insert, update and delete) on custom extra tables (also known as Z tables), I.E.: Those tables which start with the prefix Z_ and have at least present these fields: id, description_es, created_date, modified_date, deleted_date and deleted.
In summary, tho use this function the system requires a table wich name with Z_ and has at least the previously mentioned fields, however, it can also contain any other fields wich are also operable.
For example, the following is an object returned by the FM RESTful API and it’s a valid Z_ table, required fields are underlined: (this is a sample output from Search List of Values by Resource Name)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | {
"deleted": "false",
"description_es": "Martillo nº 5",
"description_de": "",
"description_en": "Hammer nº 5",
"description_fr": "",
"description_it": "",
"description_pt": "",
"deleted date": "",
"created_date": "2014-02-23T11:26:19",
"modified_date": "",
"id": "3",
"intOrder": "12",
"strIdEnvironment": "10098"
} |
IMPORTANT: When interating with a list of values, some fields are read only. This means they are readable from the system, homewer, any attempt to update or insert data into the field will result in an error being returned.
The read-only fields are: id, created_date, modified_date, deleted_date and deleted.
Inserting Lists of Values
To insert a new record use the HTTP POST method for the values and include the data in the request body as a JSON object.
1 | curl -H "Accept: application/json" -H "Content-Type: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]" -X POST d@[file_route] [FM_ENDPOINT]/api/values |
Where [file_route] is a text file containing the value’s data; in this case, it should be in JSON format (as specified on the Content-Type header), for example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | {
"resourceName": "Name of the Z table",
"data": "",
{
"field_1": "Value field 1",
"field_2": "",
...
"field_n": "Value field n",
"z_field_1": "Value Z field 1",
"z_field_2": "Value Z field 2",
...
"z_field_m": "Value Z field m"
} } |
Where ResourceName is the name of the Z_ table and data is a JSON object with the values’ data fields.
You will notice, this format is slightly different from the regular one (the one shown to operate over all the other entities and shown in the section: Creating Records).
The next table shows the possible responses when creating records on the FM System:
Response Code | Meaning | Body |
201 | The value was created successful | Status message with the Entity’s id. |
400 | The request is badly formed, probably the input file is in an invalid format. | Status message with the validation errors. |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Updating Lists of Values
To update an existing value use the HTTP PUT method, include the data in the request body as a JSON object and specify the values’ identifier.
1 | curl -H "Accept: application/json" -H "Content-Type: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]" -H "X-FM-Signature: [Message_Signature]" -X PUT d@[file_route] [FM_ENDPOINT]/api/values/[value_id] |
Where [file_route] is a text file containing the object’s data, [value_id] is the id of the value on the FM System. This file has the same format as explained in the previous section. I.E.: a ResourceName must be provided and the value’s data is enclosed in a JSON object called “data”.
It’s important to notice that when updating records, if an entity field is present on the request body and is blank, this field will be set to null on the FM System. If you want to leave a field intact, you must not include it on the request.
The next table shows the possible responses when updating values on the FM System:
Response Code | Meaning | Body |
200 | The value was updated successful | Short status message |
304 | The value wasn’t updated, probably doesn’t exist on the FM System. | No body |
400 | The request is badly formed, probably the input file is in an invalid format. | Status message with the validation errors. |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Deleting Lists of Values
To delete an existing value use the HTTP DELETE method, you must specify the value’s identifier.
1
2 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]"
-H "X-FM-Signature: [Message_Signature]" -X DELETE d@[file_route] [FM_ENDPOINT]/api/values/[value_id] |
Where [file_route] is a text file containing the object’s data, [value_id] is the id of the entity on the FM System. This file is quite similar to the one explained previously in this section, but only contains the ResourceName field:
1
2
3 | {
"resourceName": "Name of the Z table"
} |
The next table shows the possible responses when updating records on the FM System:
Response Code | Meaning | Body |
200 | The value was deleted successfully | Short status message |
400 | The request is badly formed, probably the id is not a valid positive integer. | Status message with the validation errors |
500 | Internal server error, you could try to send the request after some time. | Short status message |
Working with related Entities
A related or linked entity is an object that depends on other, it’s the typical has-a relationship on the Object Oriented Design world, where the part object(s) depend(s) on other called composite.
In the FM system there are several related entities, for example, an activity can have multiple related documents:
To operate related documents, it’s required to have the id of the composite object. For example to delete the Document 2 on the previous image, it is needed the id for the Activity.
To perform requests on parts the following syntax for the url is used:
1 | [FM_ENDPOINT]/api/[composite entity]/[composite entity id]/[part entity]/[optional part entity id] |
The next table shows the values supported for the FM RESTful API to operate related entities:
Composite entity | Part entity | Result ( GET) | Description |
Activities | Documents | List of Documents for Activities | Used to operate the documents linked to an activity |
Searching Parts Objects
To get a full non-paginated list of parts objects, you should perform an HTTP GET method to the specific composite entity’s resource using the composite id.
1
2 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]"
-H "X-FM-Signature: [Message_Signature]" [FM_ENDPOINT]/api/[composite entity]/[composite entity id]/[part entity] |
For example, to get the documents linked to an activity (we will suppose that activity id: 1234), the query would look like:
1
2 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]"
-H "X-FM-Signature: [Message_Signature]" [FM_ENDPOINT]/api/activities/1234/documents |
IMPORTANT: Only a limited combinations of composite-part objects is supported, as defined in the previous table.
The next table shows the possible responses when obtaining records on the FM System:
Response Code | Meaning | Body |
200 | List obtained successfully | The list of entities wich can have a length of zero or one item. |
400 | The request is badly formed, probably the is negativ | Status message with the validation errors |
500 | Internal server error, you could try to send the request after some time. | Short status message. |
Deleting Parts Objects
To delete a specific part object, call the HTTP DELETE method using the following request format and specifying both entity’s identifiers.
1
2
3 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]"
-H "X-FM-Signature: [Message_Signature]" -X DELETE
[FM_ENDPOINT]/api/[composite entity]/[composite entity id]/[part entity]/[part entity id] |
For example, to delete the document with id: 90 linked to the activity with id: 1234, the request would be:
1
2 | curl -H "Accept: application/json" -H "X-FM-PublicKey: [FM_Public_Key]" -H "X-FM-UnixTimestamp: [UnixTimestamp]"
-H "X-FM-Signature: [Message_Signature]" -X DELETE [FM_ENDPOINT]/api/activities/1234/documents/90 |
The next table shows the possible responses when deleting parts records on the FM System:
Response Code | Meaning | Body |
200 | The value was deleted successfully | Short status message |
400 | The request is badly formed, probably the id is not a valid positive integer | Status message with the validation errors |
500 | Internal server error, you could try to send the request after some time. | Short status message. |
Working with FM API Specific Formats
In this section we will explain how to operate with those resource fields with special formats, they are:
Booleans
Dates
Numbers
Strings (quotes)
Booleans
The Booleans in the FM RESTful API are implemented as the Strings: “True” and “False”, so, when performing operations, these two values are accepted.
For example, an advanced search to get the deleted records would be: [FM_ENDPOINT] /[resource_base]?q=deleted=’true’
The same applies for a POST/PUT method to set a Boolean value:
1
2
3
4
5
6 | [
{
"Z_boolfield": "False",
"Z_boolfield_2": "True"
}
] |
Dates
The dates on the FM RESTful API, are ISO 8601 compatible in UTC. The exact format is YYYY-MM-DDThh:mm:ss (without the ‘Z’ UTC designator). For example, 2014-03-05T08:15:30 means March 5th of 2014 @ 08:15:30 AM in UTC.
For example, an advanced search to get a range of records created in a date/time range: [FM_ENDPOINT] /[resource_base]?q=created_date BETWEEN ‘2014-03-01T00:00:00’ AND ‘2014-03-31T00:00:00’
Numbers
The numbers in the FM RESTful API, has a dot (.) as decimal symbol; and doesn’t has any for digit grouping, for example, these are valid numbers:
2
-6.9
2323452.519
These are invalid:
2,524,127
3,6
2.611.793
Strings (quotes)
There are some strings which contains some characters that need to be treated in a special way. Those aresingle quotes (‘) and double quotes (“).
Single quotes are problematic because the advanced search uses them to mark strings. E.G.: companies?q=city_name=’L’Hospitalet’
Double quotes have limitations because the JSON format to send and receive data uses them to limit all information. E.G.:
1
2
3
4
5
6
7 | {
"account_type_id":"25",
"address_1":"L"Hospitalet",
"address_2":"",
"branch_id":"32",
...
} |
Both previous examples are incorrect, the problem is present in the grayed area on each one, the RESTful API would raise errors due to the fact that the quotes are not escaped.
The next table summarizes how to proceed on all cases:
Domain | Single quotes | Double quotes |
Json data transfer: PUT, POST and GET | N/A. The JSON supports the ' natively. E.G.: | Escape the " with a backslash (\). E.G.: |
Important fields search | N/A. Supported natively. E.G.: | N/A. Supported natively. E.G.: |
Advanced search | Not supported. However there is an alternative: instead of search using equality, it is better to perform a LIKE operation with a single character match (using underscore) for the single quote. E.G.: | N/A. Supported natively. E.G.: |