Connect & communicate
Introduction
In order to connect and communicate effectively with the Integration Platform API one needs to understand and adhere to the following rules, guidelines and best practices for efficient integration flows. Be sure to read through and understand the details outlined on this page before you start doing any hands-on integration work.
Environments
Production
All production access is obtained using this address. Be sure to quality assure your integration thoroughly before putting it into production.
Production address format: https://api.{HOSTNAME}/api/
Sandbox
All development and testing should be conducted using a sandbox environment. There are several sandbox environments and they are all accessed through specific environment prefixes. Consult your API account details for exact addresses to the sandboxes you have access to, since it depends on your integration license level.
Sandbox address format: https://api.{env}.{HOSTNAME}/api/
Protocol
The application protocol used is HTTP 1.1
as defined in RFC 2616. HTTP/2
(RFC 7540) is not supported at the moment, neither is HTTP 1.0
or HTTP 0.9
. Clients must use HTTPS when interacting with the API. Clients must not ever use plain unencrypted HTTP as this can result in authentication details being exposed.
Request methods
The HTTP
protocol defines a number of methods (commands) and these are the ones supported by the Integration Platform API.
GET
- Method to retrieve a record.
GET
requests must not contain a request body. The server will either provide the record requested or an Error. PUT
- Method to update a record. The record will be created and the current record state will be available in the response body upon successful operation, or an Error on failure.
- Also note that
PUT
supports partial modifications to a record which is why you will not ever use thePATCH
method explicitly throughout the API. POST
- Method to create a new record. The record will be created and the current record state will be available in the response body upon successful operation, or an Error on failure.
DELETE
- Method to remove a record. Only some record types are possible to
DELETE
in the Integration Platform and upon successfulDELETE
the record will be kept but marked asisDeleted: true
.
Filter response
The API-response can be filtered for most API-endpoints. The first level in the json object can be filtered on fields names. The filter can be used to minimize the API-response to the fields that is relevant for the API-consumer.
Example: the result below can be filtered to only include sku with ?includeFields=sku,stock
{
"title": "A title",
"sku": "A sku",
"stock": "10",
"...": "..."
}
the result will be
{
"sku": "A sku",
"stock": "10"
}
Query parameters
includeFields
- Define fields that should be present in the response. Available fields for each endpoint is defined in the OpenApi definition.
includeFields
can contain a string with multiple values separated by,
e.g?includeFields=field1,field2
. It is also possible to send the fields parameter multiple times e.g?includeFields=field1&includeFields=field2
. excludeFields
- Define fields that should be excluded from the response. Available fields for each endpoint is defined in the OpenApi definition.
excludeFields
can contain a string with multiple values separated by,
e.g?excludeFields=field1,field2
. It is also possible to send the fields parameter multiple times e.g?excludeFields=field1&excludeFields=fields2
.
Status codes
All method requests will yield an HTTP
response status indicating whether the request was successful or not. The status codes are logically grouped (RFC 2616) as follows:
- Informational responses
- Status code class range
100
–199
- Successful responses
- Status code class range
200
–299
- Redirection messages
- Status code class range
300
–399
- Client error responses
- Status code class range
400
–499
- Server error responses
- Status code class range
500
–599
Encoding
Responses from the API are UTF-8 encoded and Requests must be UTF-8 encoded.
Rate limit
The Integration Platform use a rate limiter per Tenant or Reseller. The current rate limit is 10 requests/s with an allowed burst of 25 requests. An exceeded rate of request will cause an increasing delay of the response.
The rate limiter is implemented using a token bucket approach. The bucket will contain a maximum of 25 tokens. Ten new tokens are added every second. A burst of 25 requests would empty the bucket and cause a delay for every following request until the bucket gets new tokens.
Exceeding the limit
The first strategy is to delay the requests but an excessive request rate can cause a rejection response with HTTP status code 429 (Too Many Requests)
.
Authentication
HTTP Basic Auth is used. Due to this it is required that HTTPS is used at all times. The Integration Platform will reject requests using HTTP only, however this may still cause client credentials to be exposed unencrypted and it is therefore vital that clients never use plain HTTP requests.
Headers
Authentication is achieved using HTTP Basic Auth with a few special HTTP
headers. Required HTTP
headers are;
X-Tenant
- Specifies tenant (by code name) to interact with.
X-ConnectionId
- Specifies the specific Connection Id for the API Connector on the Tenant to interact with.
Authorization
HTTP Basic Auth
header and value should therefore have the format likeBasic BASE64(UTF8(<username>:<password>))
.
Authentication example
$ curl
-u '<USERNAME>':'<PASSWORD>'
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/
User agent
The User-Agent
header is not required, however it is recommended that one is provided containing your application name and possibly some contact information. Sending this information will aid in troubleshooting and debugging in the future.
Clients sending the User-Agent
header must ensure it is correctly formatted according to RFC 2616. If the client wishes to provide an app name and a contact email address it must be encoded as the following example since @-chars are not allowed everywhere in User-Agent
headers.
User agent example
$ curl
-u '<USERNAME>':'<PASSWORD>' \
-F 'User-Agent: my-app/1.0 (YOURADDRESS@example.com)' \
-H 'X-Tenant: <TENANT CODE>' \
-H 'X-ConnectionId: <CONNECTION ID>' \
https://api.{HOSTNAME}/api/
Errors
Errors are communicated in two ways:
- All errors are signaled using the appropriate
HTTP
error codes, as defined in RFC 2616. - The response body contains a
JSON
document with more details about the error.
Error field descriptions
The document contains these fields:
error
- This field is always set to true.
time
- The server time formatted as Date time when the error occurred.
code
- A numeric error code denoting the type of error. A complete list of all error codes is available at errors.json.
defaultMessage
- A short human-readable version of the error.
message
- A longer human-readable version of the error if available.
helpText
- A more elaborate human-readable help text if available.
field
- Which field in the record this error relates to.
fieldValue
- The current value of the field this error relates to.
helpText
- A longer text trying to more in-depth explain the error.
class
- Internal Integration Platform component generating the error.
errorCategory
- The type of error where possible values are:
NotFound
- The requested resource was not found.InvalidData
- Supplied input data invalid.TypeError
- You don’t conform to the schema, see Data types chapter.PermissionDenied
- You don’t have permission to access the resource.RemoteAuthFailed
- Authentication to the remote system failed.Conflict
- The request yielded a conflict where, for example, you tried to create a Product with an SKU already existing on the Tenant.InvalidSettings
- Settings provided in the query didn’t pass validations.InternalError
- Something went wrong within the Integration Platform. If the problem persists, please contact us.RemoteSystemError
- Something went wrong in the communication to the remote system.
Keep in mind that the message texts listed are only the defaults. The messages are usually elaborated when generating the error to provide more information.
Error example
{
"error": true,
"time": "2019-06-05T06:58:34Z",
"code": 100002,
"subCode": 101019,
"message": "Field test field cannot be ordered by",
"defaultMessage": "Field test field cannot be ordered by",
"field": "field",
"fieldValue": "unsortableField",
"helpText": null,
"class": "record.product.proto.ProductError$ProductFieldNotSortable"
}