Headers
When communicating with EVA via services, you're never just transmitting the properties contained in the services, the data is sent (and received) with headers attached to them.
There are various uses to headers, which themselves we can broadly split up in request and response headers. The former allows you to transmit extra information to EVA, while the latter lets you optionally receive extra information.
Some headers are absolutely essential, such as the EVA-User-Agent
for example (allowing EVA to identify you), which will fail the call if it's not added.
Most however are optional, to allow you access to secure services by means of the Authorization
headers for example, or to let you change the kind of ID you communicate with.
Request headers
There are a bunch of request headers. To make it slightly more digestible, we'll try and group these in categories.
Basic request headers
Let's start off with some of the basic request headers. Although not all technically required, most calls will need these in some form.
Name | Purpose | Notes | Required |
---|---|---|---|
EVA-User-Agent | Identifies the client making the call. | Required for access management and analytical purposes by the EVA backend . | ✅ |
Authorization | User authentication token as received from the Login request. | If omitted calls will be made in an anonymous context. | Depends on service called. |
EVA-App-Token | Authentication to distinguish between anonymous calls. Vital for anonymous carts. | Automatically applied by the SDK to calls when a new one is received from the backend. Ignored when a logged-in user authentication token is provided. | If no Authorization header is set. |
EVA-StationID | Currently active station identifier. | Needs to be added for legal reasons to track which station was used for calls lacking the station ID in its payload. | No, except for legal reasons. |
Finetuning the results of your response
The following headers, which are all optional, allow you to change the kind of results your service will deliver.
Name | Purpose | Notes | Required |
---|---|---|---|
Accept-Language | What language (culture) you want your response to be. | E.g. en-EN , de-AT . Lets your users choose between languages in ecom front ends. | ❌ |
EVA-Requested-OrganizationUnitID | Organization unit selection. | Can be used to indicate which organization unit a call needs to act on when not specified in its payload. | ❌ |
EVA-Requested-OrganizationUnit-Query | Organization unit selection based on a query: { Name: '...', BackendID: '...' } | Can be used to indicate which organization unit a call needs to act on when not specified in its payload. | ❌ |
Standard headers for information purposes
The following headers are all automatically added when interacting with a service.
Name | Purpose | Notes | Required |
---|---|---|---|
EVA-API-Version | The version of the API typings used in the client application SDK. | Automatically added for analytical purposes and to lock out older clients (in the future). | ✅ |
EVA-App-ContextID | Unique call identifier (UUID). | Automatically added by the SDK for analytical purposes in tracking individual calls. | ❌ |
EVA-App-ContextChainID | Unique call chain identifier (UUID). | Automatically added by the SDK for analytical purposes in tracking chains of calls. | ❌ |
EVA-App-PayloadID | Unique request payload identifier (md5 hash). | Automatically added by the SDK for analytical purposes in tracking unique request payloads. | ❌ |
EVA-Service-Name | Name of the EVA service. | Automatically added for analytical purposes. | ❌ |
ClientName | The name of the SDK being used. | Automatically added for analytical purposes. | ❌ |
ClientVersion | The SDK version used. | Automatically added for analytical purposes. | ❌ |
Changing how you can interact with services
The following three headers allow you to change the kind of IDs you can use to communicate with EVA.
Name | Purpose | Notes | Required |
---|---|---|---|
EVA-IDs-Mode | Can be set to ExternalIDs to be able to use BackendIDs instead of EVA identifiers. Can also be set to StringIDs to serialize all IDs in the response as string ( "1234" ) instead of numbers (1234 ). Can also be set to Hybrid, to allow the use of either BackendIDs or EVA IDs (by prefixing the value as "ID": "eva:xxx") | This applies to: Products, OUs, Orders, OrderLines, Shipments, Payments, and Subscriptions - See also EVA-IDs-BackendSystemID. To get the IDs back as strings, we recommend using the value of the header Hybrid. | ❌ |
EVA-IDs-BackendSystemID | Identifier of a third party integration | Used in combination with the BackendID when setting this via EVA-IDs-Mode header, so EVA can map the right order. The combination of BackendID and BackendSystemID guarantees uniqueness, useful in cases where more than one party are involved, each creating orderID's which in turn could result in overlapping numbers | ❌ |
EVA-IDs-LeniencyThreshold | Number of IDs that are allowed to be unresolved in the request. | To be used alongside EVA-IDs-Mode in case larger requests fail when some IDs go unresolved. Will return unresolved IDs in the warning header and remove these from the request. This works with ExternalID mode for specifically GetProductAvailability as well. | ❌ |
Although every service is compatible with the EVA-IDs-Mode
, not every kind of BackendID is supported. Expand the following section for a list of objects for which you can use the BackendID
EVA-IDs-Mode BackendIDs
- AddressBook
- Case
- CustomField
- OrderLine
- OrganizationUnit
- OrganizationUnitSet
- PaymentTransaction
- Product
- ProductSearchTemplate
- Role
- ShipmentLine
- Shipment
- StockMutationReasons
- Subscription
- UserField
- User
The EVA-IDs-LeniencyThreshold
is nothing but an extension on EVA-IDs-Mode
. When specifying this threshold, it will only be applied to the objects mentioned in the following list.
EVA-IDs-LeniencyThreshold
- UpdateSimplePrices.Prices
- GetProductAvailability.Products
- GetProductAvailability.Options.OrganizationUnitIDs
- GetProductAvailability.Options.ProductIDs
Examples with GetProductAvailability
The following examples show you a regular call (using EVA ID) and one where EVA-IDs-Mode
is set to ExternalIDs. Additionally, the second call has EVA-IDs-LeniencyThreshold
set to 2.
{
"Products": [{
"ID" : 14
}],
"Options" : {
"ProductAvailabilityDetails" : { }
}
}
{
"Products": [
{
"ProductID": 14,
"ProductStatus": 0,
"AvailabilityDetails": [
{
"OrganizationUnit": {
"ID": 1,
"Name": "New Black",
"BackendID": "EVA",
"Type": 4
},
"QuantityOnHand": 1,
"QuantityCommitted": 0,
"QuantityAvailable": 1,
"OrdersWaitingForStockQuantity": 0,
"SupplierQuantityCommitted": 0,
"SupplierQuantityOnHand": 0,
"SupplierQuantityAvailable": 0,
"QuantityReservedForOtherOrganizationUnits": 0,
"ExpectedAvailabilityDate": "2022-12-17T00:00:00Z"
}
]
}
],
"Metadata": {
"ExternalIDs": {
"Product": {
"002-1-978020137008": "14"
}
},
"UnresolvedExternalIDs": {}
}
}
{
"Products": [
{"ID" : "004-2-978020137025" },
{"ID" : "004-1-978020137024"},
{"ID" : "004-2-978020137023"}
],
"Options" : {
"ProductAvailabilityDetails" : { }
}
}
{
"Products": [
{
"ProductID": 36,
"ProductStatus": 0,
"AvailabilityDetails": [
{
"OrganizationUnit": {
"ID": 1,
"Name": "New Black",
"BackendID": "EVA",
"Type": 4
},
"QuantityOnHand": 0,
"QuantityCommitted": 0,
"QuantityAvailable": 0,
"OrdersWaitingForStockQuantity": 0,
"SupplierQuantityCommitted": 0,
"SupplierQuantityOnHand": 0,
"SupplierQuantityAvailable": 0,
"QuantityReservedForOtherOrganizationUnits": 0
}
]
},
{
"ProductID": 35,
"ProductStatus": 0,
"AvailabilityDetails": [
{
"OrganizationUnit": {
"ID": 1,
"Name": "New Black",
"BackendID": "EVA",
"Type": 4
},
"QuantityOnHand": 0,
"QuantityCommitted": 0,
"QuantityAvailable": 0,
"OrdersWaitingForStockQuantity": 0,
"SupplierQuantityCommitted": 0,
"SupplierQuantityOnHand": 0,
"SupplierQuantityAvailable": 0,
"QuantityReservedForOtherOrganizationUnits": 0
}
]
}
],
"Metadata": {
"ExternalIDs": {
"Product": {
"004-1-978020137024": "35",
"004-2-978020137025": "36"
}
},
"UnresolvedExternalIDs": {
"Product": [
"004-2-978020137023"
]
}
}
}
In the last call one out of three ProductIDs is incorrect, as shown in the UnresolvedExternalIDs property at the bottom. If we were to have added more than 2 incorrect ones, the service would error out as expected with the following error message.
{
"Error": {
"Message": "The service reached the leniency threshold (2) trying to resolve the external IDs for entity type Product",
"Type": "ExternalIDsLeniencyThresholdReachedException",
"Code": "CDDLDLGU",
"RequestID": "9e0580be9174cd6a4771355541021566"
}
}
Response headers
Below is the list of headers that can be received from the EVA backend
Name | Purpose | Notes | Required |
---|---|---|---|
EVA-App-Token | New anonymous application token to be used on consecutive calls. | Automatically picked up by the SDK and applied to any future calls. | ❌ |
EVA-Warning | Inform clients about using deprecated features or other notices. | Can be sent multiple times. | ❌ |
EVA-OrganizationUnit-ExternalIDs-Map | x | x | ❌ |
EVA-Product-ExternalIDs-Map | x | x | ❌ |
Content-Security-Policy | Standard CORS response for security purposes | Can be enabled by setting Cors:ContentSecurityPolicy to true (defaults to false). EVA will then reply with the following value in this header: default-src 'none'; frame-ancestors 'none' | ❌ |
Access-Control-Allow-Origin | CORS Whitelisting | By entering comma-separated values in the Cors:AccessControlAllowOrigin setting (defaults to null), this response header will now only echo the request header Origin if it is present in this whitelisted set of configured values. A single wildcard (*) per entry is supported. | ❌ |
We want to stress the importance of the EVA-Warning
response header: Make sure to ALWAYS catch this header on responses and ALWAYS resolve any warning we return.