Skip to main content

Offer Sumission API

Introduction

The Offer Submission API is organized around REST. Our API has predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

This API gives users the ability to submit new offers for approval and assign offers to customers.

This API uses the oAuth2 client credentials grant type to secure all the communications. For more information, check the Authentication/Authorization guide.

Use Cases

A faster and error-proof way of creating offers

Offers Submission API gives to the CRM Ops Team a process to create offers with an UI simplified and smart, to increase the speed of offer synchronisation across the landscape while reducing failure rates, so that end users ability and trust increases to fully leverage the full capabilities of offers.

Benefits

Focus on improving the experience of creating offers for CRM Ops Team, the benefits of this new platform and API includes:

  • New digital experience for offers creators

    The CRM Ops Team should have a new digital experience when creation offers, with a simple and intuitive user interface, and preview options, for a real time demonstration of how the offer would look both on the website or the app in the mobile devices.

  • Real time offer creation

    A new capability of real time offer creation will be added to enable creating and updating offers in real time, across all systems involved in creating, managing and publish new offers. These offers can take seconds to create!

  • Reduce reengineering on offers creation process

    During the creation of the new platform for offers creation, users were engaged in the process, having the opportunity to give feedback to improve the process, examine ways of working to achieve a streamline and simple process, and creating awareness in all functionalities in offers creation process.

    It was also enabled the option to publish the offer to PROD from UAT, with appropriate approvals (reducing the need to recreate offers in PROD).

  • Real time error feedback

    The new platform aims powering real time validation of the inserted values, previewing the offer during creation by simulating the different views and enabling end to end testing by assigning to test users in realtime, achieving minimum failure rates with near realtime error status report. The feedback provided to users enables editing failed offers rapidly, by letting them know what went wrong and how to fix the issues.

  • Reduce time-to-live of offers to the client

    It was possible to create an ecosystem to synchronise the offers seamlessly across the landscape with minimum failure rate, since APIs creation could become the bedrock of automated processes, which increases the speed of creation of offers (eg. by reusing templates as base).

    Time to create and publish offers was reduce from 10 days to 30 minutes, in some cases.

  • Increase clients trust on offers

    Creating offers without errors and within minimum time to create and publish, and enabling end to end offers testing will result in tailored offers, more aligned with clients needs, increasing the level of trust that clients are having in the offers presented.

    Marketing teams could react in-real-time to world changes, resulting in a well designed Offer Decision Engine and an improved match process between assigned offers to client according to each clients needs.

  • Multi Language Approach

    Offer creators can now add details (eg. Offer title, description, messages, etc) in multiple languages based on the allowed languages of a market.

    To help Reporting and Analytics teams, english details can be passed along also too, for non-English markets.

Quick Start Guide for Offer Submission API

This API is secured by OAuth 2.0. It uses the 'Client Credentials' Grant Type to allow the API consumer to access data. The process is details with the diagram below.

sequenceDiagram activate Partner Application Partner Application-)+Shell ServiceNow: 1. Request a Client ID and a Client Secret Shell ServiceNow--)-Partner Application: 2. Generate and provide Client ID and Client Secret Partner Application->>+Auth API: 3. Request an Access Token Auth API-->>-Partner Application: token, token_type, expires_at Partner Application->>+Offer Submission API: 4. Initiate request to Offer Submission API with the Access token from previous step Offer Submission API-->>-Partner Application: Returns a response after validation of the Access Token deactivate Partner Application

Base URLs

Auth API

Environment Base URL
QA https://azmsauthqa.azurewebsites.net/
UAT https://azmsauthuat.azurewebsites.net/
PROD https://azmsauth.azurewebsites.net/

Offer Submission API

Environment Base URL
QA https://offermanagementapis-qa.azurewebsites.net/
UAT https://offermanagementapis-uat.azurewebsites.net/
PROD https://offermanagementapis.azurewebsites.net/

1. Request a Client ID and a Client Secret

To use the Offer Submission API, you first need to request a Client ID and a Client Secret using Shell ServiceNow service.

Select the SIMAAS - Self-Service Application Onboarding (Production/Non-Production). First, you need to ask for non-Production access. When asked about an Application CI, select RTL_MOB_MICRO_OFFERS_MGMT PBS00719857.

2. Generate and provide Client ID and Client Secret

They will generate the credentials and send you by email.

3. Request an Access Token

Once you received the client credentials, just make a POST request to /auth/v1/token endpoint.

Request body parameters

REQUEST BODY PARAMETER VALUE
grant_type Required
It is the grant mode type, use client_credentials
client_id It is the Client ID you received.
client_secret It is the Client Secret you received.

Sample Request

curl --location 'https://azmsauthqa.azurewebsites.net/auth/v1/token' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
  "grant_type": "client_credentials",
  "client_id": "***",
  "client_secret": "***"
}'

Response

On success, the response will have a 200 OK status and the following JSON data in the response body: | KEY | VALUE TYPE | VALUE DESCRIPTION | | --- | --- | --- | | expires_at | string | The number of seconds since the epoch when this token will expire. | | token | string | The access_token in JWT format. | | token_type | string | The type of the token: Bearer. |

Note: This endpoint doesn't return a refresh token. Hence in case the bearer token expires the same endpoint should be called again to retrieve a new bearer token.

Sample Response

{
  "expires_at": "1665767738",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
  "token_type": "Bearer"
}

4. Initiate request to Offer Submission API with the Access Token from previous step

Every request you make to the Offer Submission API should include the Authorization header:

Header Parameters

HEADER PARAMETER DATA TYPE DESCRIPTION
Authorization String This is a Bearer token. It should be the Access Token you got when you requested an Access Token before.

Example: Bearer xxx where xxx is your Access Token.
Example: Bearer xxx where xxx is your Access Token.

Troubleshooting Authentication

The following table lists common authentication errors and potential causes:

HTTP STATUS CODE VALUE POSSIBLE CAUSES
400 Bad request Missing or incorrect parameters or header values.
401 Unauthorized User not found.

Fundamentals

Requests

The Offer Submission API provides a set of endpoints, each with its unique path. It is based on REST principles. Data resources are accessed via standard HTTPS requests in UTF-8 format. List of verbs in Offer Submission API:

  • POST - Performs an action.

Responses

The responses always include a JSON object. Check the API documentation to find descriptions of common responses for each endpoint.

Response Status Codes

The Offer Submission API uses the following response status codes defined in RFC 2616 and RFC 6585.

  • 200 - The request has succeeded. The Partner application can read the result of the request in the body and the headers of the response.
  • 400 - Bad request. Due to malformed syntax, the server could not understand the request. The body will contain more information.
  • 401 - Unauthorized. The request requires user authentication, and it has been refused for those credentials.
  • 403 - Forbidden. The server understood the request but is refusing to fulfill it.
  • 404 - Not Found - The requested resource could not be found. This error can be due to a temporary or permanent condition.
  • 422 - Unprocessable content. The server understood the request but is unable to process it.
  • 500 - Internal Server Error. This error should not happen but if you receive it, something went wrong, please report it to us.

Response Error Schemas

All error scenarios are returned with the same response body structure:

{
  "error": {
    "Developer": {
      "appErrorCode": "string",
      "message": "string",
      "reason": "string"
    },
    "User": {
      "appErrorCode": "string",
      "message": "string",
      "reason": "string"
    }
  },
  "errorCode": 0,
  "message": "string"
}
KEY VALUE TYPE VALUE DESCRIPTION
errorCode Int The status code of the error.
message String The generic HTTP error message. For example, 500 is Internal Server Error.
error JSON An object with two JSONs with more details for the user and the developer.
error.User JSON An object with details for the User.
error.User.appErrorCode String An error code from the Offer Submission API.
error.User.message String An error message you can show to your users.
error.User.reason String A reason message.
error.Developer JSON An object with details for the User.
error.Developer.appErrorCode String The same error code from the Offer Submission API.
error.Developer.message String An error message giving details about the error. This can be useful for debugging your application.
error.Developer.reason String A reason message.

Versioning

Your API version controls the API behavior you see (what properties you see in responses, what parameters you're allowed to send in requests, and so on). Your version is set in the URL. When a breaking change is introduced to the Offer Submission API, an updated version is released. The current version is v1. This is the only version available at this moment.

Backwards-compatible changes

We consider the following changes to be backward-compatible:

  • Adding new API resources.
  • Adding new optional request parameters to existing API endpoints.
  • Adding new properties to existing API responses.
  • Changing the order of properties in existing API responses.
  • Changing the length or format of opaque strings, such as object IDs, error messages, and other human-readable strings.

Security

The Offer Submission API forces HTTPS for all services using TLS (SSL).

The Offer Submission API uses IP Whitelisting to help prevent attacks against the API. Only trusted IP addresses will be able to submit requests to the API.

List endpoints and resource name

Request an Access Token

This endpoint of the Auth API https://azmsauthqa.azurewebsites.net/auth/v1/token uses the HTTP POST method.

Request body parameters

REQUEST BODY PARAMETER DATA TYPE LIMITS (MIN/MAX) NULLABLE VALUE
grant_type String Enum values: client_credentials, authorization_code, refresh_token No Required
It is the grant mode type, use client_credentials

Example: client_credentials
client_id String N/A No It is the Client ID you received.

Example: ti6lsuPEhcmBVxm5
client_secret String N/A No It is the Client Secret you received.

Example: dJiWaKdVuVojMBAfaYUPDi84zvVLlWivFy7s1qLFiToNejESGn12rAybrtNoolj

Sample Request

curl --location 'https://azmsauthqa.azurewebsites.net/auth/v1/token' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
  "grant_type": "client_credentials",
  "client_id": "***",
  "client_secret": "***"
}'

When you request an Access Token, the Auth microservice will contact the Identity Provider System to get an Access Token using the client credentials provided. After getting one, the Auth microservice will ensure the user exists on our database and generate a new JWT token with the user roles, the email, and the UUID of the user. This will be returned to you alongside the token type and the expiration date of the Access Token.

Response

On success the response will have a 200 OK status and the body of the response will contain a simple JSON object with:

KEY NULLABLE VALUE TYPE DESCRIPTION
expires_at No String The number of seconds since epoch when this token will expire.
token No String The access token in JWT format.
token_type No String The type of the token: Bearer.

Sample Response

{
  "expires_at": "1665767738",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
  "token_type": "Bearer"
}

Exception Handling

The format of errors is always the same and specified in the Fundamentals section. For this endpoint, this is the list of errors:

HTTP CODE Description Scenarios/Use case
400 Bad Request Some of the parameters are not valid.
401 Unauthorized The user does not exist.

Retrieve information about the version and environment

This endpoint of the Offer Submission API https://offermanagementapis-qa.azurewebsites.net/api/v1/about uses the HTTP GET method.

Headers parameters

HEADER PARAMETER DATA TYPE LIMITS (MIN/MAX) NULLABLE DESCRIPTION
Authorization String N/A No This is a Bearer token. It should be the JWT token you got when you requested an Access Token before.

Example: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
countryCode String 2 characters No Country code in two characters ISO 3166-1 alpha-2 format. The possible values are GB, PL, BG, PH, HU.

Example: GB

Sample Request

curl --location 'https://offermanagementapis-qa.azurewebsites.net/api/v1/about' \
--header 'Authorization: Bearer ***' \
--header 'countryCode: GB' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'

Response

On success the response will have a 200 OK status and the body of the response will contain a simple JSON object with the following fields:

KEY NULLABLE VALUE TYPE DESCRIPTION
environment No String It can be one of the following values: qa, uat, and prod. It is the environment of the Offer submission API you are currently using.
version No String It is the version of the Offer Submission API you are currently using.

Sample Response

{
    "version": "1.3.0-03bc15a6f29f8b4bfb55148c6d877e37ec5fe4f5",
    "environment": "qa"
}

Exception Handling

The format of errors is always the same and specified in the Fundamentals section. For this endpoint, this is the list of errors:

HTTP CODE Description Scenarios/Use case
401 Unauthorized The user token is not valid anymore or missing.
403 Forbidden The user does not have permissions to do this action.
422 Unprocessable Content Mandatory fields are missing (countryCode for example).

Create and submit an offer

This endpoint of the Offer Submission API https://offermanagementapis-qa.azurewebsites.net/api/v1/offers/submit uses the HTTP POST method.

Headers parameters

HEADER PARAMETER DATA TYPE LIMITS (MIN/MAX) NULLABLE DESCRIPTION
Authorization String N/A No This is a Bearer token. It should be the JWT token you got when you requested an Access Token before.

Example: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
countryCode String 2 characters No Country code of the offer in the two characters ISO 3166-1 alpha-2 format. The possible values are GB, PL, BG, PH, HU.

Example: GB

Request body parameters

REQUEST BODY PARAMETER DATA TYPE LIMITS (MIN/MAX) NULLABLE DESCRIPTION
acceptanceRequired Boolean true / false Yes Specifies if the customer must accept the offer assigned.

Example: true
accumulative Boolean true / false Yes If it is true, the offer can be assigned to the customer more than once at the same time. The maximum of the owned offers is the numberOfUsage.

Example: false
assignableFrom Date Lower than assignableTo. Cannot be a past date. No Date from when the offer is available to be assigned to customers. Use the ISO 8601 date format YYYY-MM-DD.

Example: 2023-12-01.
assignableTo Date Greater than assignableFrom. Cannot be a past date. No Date until offer is available in the markets offer bank to be assigned from the offer bank. Use the ISO 8601 date format YYYY-MM-DD.

Example: 2023-12-02.
costOfReward Number (double) Only float values with a maximum of 2 decimals. Minimum is 0.00. Yes Specify how much it costs the market to give this reward.

Example: 12.25
customText Array of objects N/A No A summary of the offer for each language.
customText.language String 2 characters No The language used for the summary.

Example: en
customText.text String Max length is 4000 characters. No The text for the summary of the offer.

Example: Fill min 1L of any fuel and get 200 pts.
deactivationAllowed Boolean true / false No If it is set to true, the redemption of the offer can be activated/deactivated by the customer. A deactivated offer is not redeemable.

Example: true
displayOrder Number (integer) Min is 1. Max is 99. No Priority of offer display in the offer inbox. A lower number means higher priority. 0 will be on top.

Example: 20
expirationDays Number (integer) Min is 1. Max is 999999999999 Yes Defines the number of days the customer has to redeem the reward (is only applied if this extends the offer's validity for that customer).

Example: 30
expirationDaysAchievement Number (integer) Min is 1. Max is 999999999999 Yes Defines the number of days within which the customer has to achieve the offer (is only applied if this extends the offer's validity for that customer)

Example: 30
gameDetails Object (JSON) N/A No, only when offerType is:
- TARGETED_GAME_MASS
- GAME_MASS
Yes, for other offerType.
Contains fields related with TARGETED_GAME_MASS and GAME_MASS offer types.
gameDetails.campaignOverviewImage String Max length is 200 characters. No ID of the campaign image displayed on the app.

Example: 82dc5ab1-1ceb-5cfe-b100-8cdfa4b306a6
gameDetails.gameDescription Array of objects N/A No The brief description of the game to be displayed to the customer via the App for each language.
gameDetails.gameDescription.language String 2 characters No The language used for the brief description.

Example: en
gameDetails.gameDescription.text String Max length is 100 characters. No The text for the brief description of the game.

Example: Play every day and get 200 points.
gameDetails.gameIcon String Max length is 200 characters No Dynamo/COCO ID. This ID is for identifying the icon image on mobile view.

Example: 1234567890
gameDetails.gameTANDCURL String Max length is 200 characters No The URL of the page(s) of Terms and Conditions of the game play for the game described.

Example: http://www.example.com/terms
gameDetails.gameType String Enum values: Luck Game , Skill Game or Knowledge Game. No The description of the type of game that is defined by the Game description and URL.

Example: Luck Game
gameDetails.gameURL String Max length is 120 characters No The full URL of the game.

Example: http://www.example.com
gameDetails.inviteDurationDays Number (integer) Min is 0. Max is 999999999999 No The number of days before the invite expires. Must be rounded up to the last day’s midnight when expiring invites.

Example: 100
gameDetails.prizeDescription Array of objects N/A No An array with the descriptions of the possible prizes that may be won if the motorist wins the game for each language.
gameDetails.prizeDescription.language String 2 characters No The language used for the description of the possible prizes.

Example: en
gameDetails.prizeDescription.text String Max length is 4000 characters. No A description of the possible prizes.

Example: This a prize description.
initiallyActive Boolean true / false Yes Specifies if offer is immediately active after assignment.

Example: true
isDefault Boolean true / false No, only when offerType is:
- STAMP_SURPRISE
- GFR_SURPRISE
Yes, for other offerType.
If there is no personalized surprise offer assigned to the customer when the counter is fulfilled the customer will get the offer marked with this field true. Only one of these offers can exist per market per offer type.

Example: false
numberOfAssign Number (integer) Min is 0. Max is 999999999999 No, only when offerType is:
- TARGETED_BASIC_MASS
- TARGETED_SEASONAL_BASIC_MASS
- CONDITIONAL
- SURPRISE
- GOODWILL
- PARTNER_BMO
- PARTNER_SURPRISE
- WELCOME
- POINT_CONDITIONAL
Yes, for other offerType.
Specifies how many times the offer can be assigned to a single customer (0 = unlimited)

Example: 3
numberOfUsage Number (integer) Min is 0. Max is 999999999999 No, only when offerType is:
- CONDITIONAL
- SURPRISE
- GOODWILL
- PARTNER_SURPRISE
- WELCOME
- POINT_CONDITIONAL
- TARGETED_GAME_MASS
- GAME_MASS
Yes, for other offerType.
Specifies how many times the offer can be used by single customer per assignment.

Example: 0
offerAchievementRule Array of objects N/A No, only when offerType is:
- CONDITIONAL
- TARGETED_GFR_COUNTER
- GFR_COUNTER
- STAMP_COUNTER
Yes, for other offerType.
Defines rules the user must accomplish to earn a reward. The relationship between the rules is OR. If the achievementRuleType is COMBINED_PRODUCT_PURCHASE then the relationship will be AND.
offerAchievementRule.achievementRuleType String If offerType = CONDITIONAL,
then Enum values:
- PRODUCT_PURCHASE
- PRODUCT_PURCHASE_VALUE
- COMBINED_PRODUCT_PURCHASE.

If offerType = TARGETED_GFR_COUNTER\|GFR_COUNTER\|STAMP_COUNTER,
then Enum values:
- PRODUCT_PURCHASE
- PRODUCT_PURCHASE_VALUE
No Defines what the customer needs to do in order to earn a reward.

- PRODUCT_PURCHASE means the offer can be achieved by purchasing the number of certain producs, detailed by requiredQuantity.

- PRODUCT_PURCHASE_VALUE means the offer can be achieved by purchasing a specific value of certain products, detailed by requiredQuantity.

- COMBINED_PRODUCT_PURCHASE means the offer can be achieved by purchasing both the number of products, detailed by requiredQuantity, and the products defined within another offerAchievementRule having the achievementRuleType COMBINED_PRODUCT_PURCHASE within the same offer.

Example: PRODUCT_PURCHASE
offerAchievementRule.excludeProducts Array of Strings Each string must have between 0 and 12 characters. Yes Defines the list of products that must not be included in the transaction to achieve the offer.

Example: CG0000000163
offerAchievementRule.includeProducts Array of Strings Each string must have between 0 and 12 characters. Yes Defines the list of products that must be included in the transaction to achieve the offer.

Example: CG0000000123
offerAchievementRule.label String Min is 0. Max is 100. No, only when offerType is CONDITIONAL.
Yes, for other offerType.
Label given to the achievement rule (used if more than one rule).

Example: Rule 1
offerAchievementRule.progressIncrement Number (integer) Min is 1. Max is 999999999999. No, only when offerType is:
- TARGETED_GFR_COUNTER
- GFR_COUNTER
- STAMP_COUNTER
Yes, for other offerType.
Number of stamps awarded to the customer for fulfilling the achievement rule.

Example: 100
offerAchievementRule.requiredQuantity Number (integer) Min is 0. Max is 999999999999. No The required quantity, units/litres/monetary value, to be purchased in each transaction.

Example 50
offerAchievementRule.requiredTransactions Number (integer) Min is 0. Max is 999999999999. No, only when offerType is CONDITIONAL.
Yes, for other offerType.
Defines how many transactions need to be made so that offer gets achieved.

Example: 10
offerBackground String Max length is 200 characters. No Dynamo/COCO ID. This ID is for displaying background image on web/mobile view.

Example: 82dc5ab1-1ceb-5cfe-b100-8cdfa4b306a6
offerCode String Max length is 30 characters. Yes, only when offerType is:
- BASIC_MASS
- SURPRISE
- CONDITIONAL
- POINT_CONDITIONAL
- TARGETED_BASIC_MASSS
- PARTNER_BMO
No, for other offerType.
Unique code for each offer, used to refer to offers in tech offer list and data brief.

Example: 1234567890
offerDescription Array N/A No Description of the offer for each language.
offerDescription.language String 2 characters No Language of the description of the offer.

Example: en
offerDescripcion.text String Max length is 4000 characters. No Description of the offer.

Example: Fill min 1L of any fuel and get 200 pts
offerName String Max length is 100 characters. No Name of the offer.

Example: New offer
offerReceiptMessage Array of objects N/A Yes Custom receipt message triggered when the offer is rewarded for each language.
offerReceiptMessage.language String 2 characters No, if the array is not nil. Language of the receipt message.

Example: en
offerReceiptMessage.text String Max length is 4000 characters No, if the array is not nil. Custom receipt message triggered when the offer is rewarded.

Example: Fill min 1L of any fuel and get 200 pts
offerResetDay Number (integer) Min is 1. Max is 28. No, only when offerType is PARTNER_BMO.
Yes, for other offer_type.
Day of month when the offer reward limit is reset.

Example: 12
offerRewardConditionRule Array of objects - If offerType = POINT_CONDITIONAL, then exactly 2 objects are required.
- If offerType = TARGETED_GAME_MASS\|GAME_MASS\|TARGETED_BASIC_MASS\|TARGETED_SEASONAL_BASIC_MASS, then exactly 1 object is required.
- If offerType = STAMP_SURPRISE\|GFR_SURPRISE, then the min number of objects is 0 and max is 2.
- For other offerType, only one condition rule is allowed.
Yes, only when offerType is:
- WELCOME
- GOODWILL
- PARTNER_SURPRISE
- PARTNER_BMO
No, for other offer_type.
Defines the condition the customer’s transation must meet to get the offer rewarded.
offerRewardConditionRule.conditionRuleType String Enum values:
- SPENT_AMOUNT
- PRODUCT_PURCHASE
- PRODUCT_PURCHASE_VALUE

If offerType = POINT_CONDITIONAL, then also:
- REQUIRED_POINT_VALUE
No, if the array is not nil. If offerType = POINT_CONDITIONAL, then one of the offerRewardConditionRule object is of type REQUIRED_POINT_VALUE and the other is of another type.

Example: SPENT_AMOUNT
offerRewardConditionRule.productCode String Max is 12 characters. No, if the array is not nil. More details in description. If offerType = POINT_CONDITIONAL, then this field is required for the first rule. For the second rule, is optional.

It is a Product Custom Group code. This code must exist in LoD.

Example: CG0000000163
offerRewardConditionRule.requiredValue Number (double) Max is 9999999999.0. No, if the array is not nil. The value for which the OFFER_REWARD_CONDITION_RULE_TYPE must be met for the offer to be rewarded.

- SPENT_AMOUNT: the value of the basket (before any discounts applied).

- PRODUCT_PURCHASE: how much of a given product the customer must buy.

- PRODUCT_PURCHASE_VALUE: the value of a given product purchased (without the offer applied).

- REQUIRED_POINT_VALUE: the customer must have at least these many points on her account.

Example: 12.5
offerRewardRule Object (JSON) Only one reward rule by offer. Yes, if offerType is:
- STAMP_COUNTER
- TARGETED_GFR_COUNTER
No, for other offerType.
One offer can contain one reward rule.
offerRewardRule.productCode String Max is 12 characters. No The product custom group for which the offerRewardRule is applicable. It must exist in LoD.

Example: CG0000000163
offerRewardRule.rewardIncrement Number (integer) Max is 9999999999. Yes Unit of measure for getting reward. Calculation of reward quantity:

[ROUNDING(Quantity / rewardIncrement)] * rewardIncrement

The rounding rule is defined by rounding.

This field is only usable in case of ruleType is:
- UNIT_BASED_PERCENTAGE
- UNIT_BASED_DISCOUNT

Example: 1000
offerRewardRule.rewardLimit Number (double) Max is 9999999999.0 No, if offerType = PARTNER_BMO and ruleType = UNIT_BASED_PERCENTAGE\|UNIT_BASED_DISCOUNT.
Yes, for other offerType.
Quantity based limit for unit-based reward rule types.

This field is only usable in case of ruleType is:
- UNIT_BASED_PERCENTAGE
- UNIT_BASED_DISCOUNT

Example: 1000.5
offerRewardRule.rewardValue Number (double) Max is 9999999999.0 No It is the value of the reward, depends on the ruleType:

- FIX_POINTS: Number of points to be rewarded to the customer.

- POINTS_MULTIPLIER: In this case, the customer gets the basic points (from basic awarding rules), and in a separate detail line get the (basic points x point_multiplier-1). This field specifies the multiplier.

- FREE_PRODUCT: How many products the customer will get for free.

- UNIT_BASED_PRODUCT: How much discount (price) is given per piece of product purchased.

- PRODUCT_BASED_DISCOUNT: Total discount (price) provided. Only applied to one piece of the line item.

- PRODUCT_BASED_PERCENTAGE: How much discount (percentage) is provided. Only applied to one piece of the line item.

- UNIT_BASED_PERCENTAGE: How much discount (percentage) is given per piece of product purchased.

- FIX_DISCOUNT: How much discount (price) is given. Fix value discount on the line item. The total value of the line item must be larger than or equal to the value of the FIX_DISCOUNT.


Example: 100.5
offerRewardRule.rounding String Enum values:
- DOWN
- UP
- MATH
Yes See rewardIncrement.

Example: UP
offerRewardRule.ruleType String Enum values:
- FREE_PRODUCT
- FIX_DISCOUNT
- UNIT_BASED_DISCOUNT
- UNIT_BASED_PERCENTAGE
- PRODUCT_BASED_DISCOUNT
- PRODUCT_BASED_PERCENTAGE
- FIX_POINTS
- POINTS_MULTIPLIER
- VISIT_BOOST
- GAME_INVITATION
No Type of discount.

See table for the possible values for each offerType.

Example: FREE_PRODUCT
offerSubtype String Enum value:
- GIVEAWAY
Yes Offer sub-type should be GIVEAWAY for all the offers which need to be reimbursed to the retailers (discount/free product), dependent on the reimbursement set up in the given country. Does not drive any offer-related functionalities. Failing to select offer sub-type as a giveaway can prevent retailers from being reimbursed through GSAP, please check your setup.

Example: GIVEAWAY
offerTitle Array of objects N/A No The title of the offer for each language
offerTitle.language String 2 characters No The language of the offer’s title.

Example: en
offerTitle.text String Max length is 200 characters. No The title.

Example: 10% discount on Shell Helix
offerType String Enum values:
- BASIC_MASS
- CONDITIONAL
- GAME_MASS
- GFR_COUNTER
- GFR_SURPRISE
- GOODWILL
- PARTNER_BMO
- PARTNER_SURPRISE
- POINT_CONDITIONAL
- POWER_UP
- SEASONAL_BASIC_MASS
- STAMP_COUNTER
- STAMP_SURPRISE
- SURPRISE
- TARGETED_BASIC_MASS
- TARGETED_GAME_MASS
- TARGETED_GFR_COUNTER
- TARGETED_SEASONAL_BASIC_MASS
- VISIT_BOOST
- WELCOME
No Type of the offer.

Example: BASIC_MASS
partialRewardOffer Boolean true / false Yes Defines whether reward can be split up over multiple transactions.

Example: false
partnerCode String Max length is 12 characters. No, when offerType is:
- PARTNER_BMO
- PARTNER_SURPRISE
Yes, for other offerType.
Defines the specific Partner. Used for Partner offers. Must exist in loyalty management.

Example: RAC
partnerFundingPercentage Number (double) Max is 100.0. - No, when partnerCode is not empty and offerRewardRule.ruleType is not FIX_POINTS or POINTS_MULTIPLIER.
- No, when previous condition is false and offerType is:
  - PARTNER_BMO
  - PARTNER_SUPRISE
- Yes, for other cases.
For partner offers it gives the percentage that the partner pays of the discount amount. Not processed in point-based offers (where offerRewardRule.ruleType is either FIX_POINTS or POINTS_MULTIPLIER).

Example: 12.5
partnerPointsValue Number (double) N/A No, when partnerCode is not empty and offerRewardRule.ruleType is FIX_POINTS or POINTS_MULTIPLIER.
Yes, for other cases.
Cash value of point-based offers. Used for partner billing calculations. Usable only in point-based offers (point-based offer: offerRewardRule.ruleType is FIX_POINTS or POINTS_MULTIPLIER). Works only if the partnerCode is filled. The currency is market specific, always the main, local currency of the market (Euro, Zloty, Forint, ...)

Example: 10.5
qualifyingVisitTarget Number (integer) Max is 999999999999. No, when offerType is:
- TARGETED_GFR_COUNTER
- GFR_COUNTER
Yes, for other offerType.
Number of QVs customer needs to collect to complete tracker cycle. Only used in the UK.

Example: 10
replacedOfferCode Number (integer) Max is 999999999999. No, when offerType = POWER_UP.
Yes, for other offerType.
Basic Mass Offer ID that needs to be boosted by the POWER_UP.

Example: 100
requiredStamp Number (integer) Max is 999999999999. No, when offerType is:
- POWER_UP
- STAMP_COUNTER
Yes, for other offerType.
Number of targeted stamps to complete the cycle, Optional for TH/PH for stamp counter and targeted stamp counter.

Example: 10
retailSite String Max length is 200 characters. Yes Site where the offer can be used.

Example: 82dc5ab1-1ceb-5cfe-b100-8cdfa4b306a6
rewardEngineExcluded Boolean true / false Yes Defines whether offer should be excluded from ODE offer bank.

Example: true
validityLimitation String Max length is 30 characters. Yes To have an offer that is available only on certain date (for example: every Friday; every day between 3-4PM; until 15 May).

Example: Every Friday
validityStartOffset Number (integer) Min is 1. Max is 999999999999. No, when offerType is:
GFR_SURPRISE
- STAMP_COUNTER
- STAMP_SURPRISE
Yes, for other offerType.
Defines number of days when the reward will be assigned after the cycle is completed.

Example: 15
visibleFrom Date Date Format should be YYYY-MM-DD. Yes Date from which the offer will be visible in frontend apps.

Example: 2023-12-01

Availability of reward rule types by each offer type

Offer Type by Reward Rule Type FREE_PRODUCT FIX_DISCOUNT UNIT_BASED_DISCOUNT UNIT_BASED_PERCENTAGE PRODUCT_BASED_DISCOUNT PRODUCT_BASED_PERCENTAGE FIX_POINTS POINTS_MULTIPLIER VISIT_BOOST GAME_INVITATION
BASIC_MASS N/A X X X N/A N/A X X N/A N/A
TARGETED_BASIC_MASS X X X X X X N/A X N/A N/A
SEASONAL_BASIC_MASS X X X X X X N/A X N/A N/A
TARGETED_SEASONAL_BASIC_MASS X X X X X X N/A X N/A N/A
CONDITIONAL X X X X X X X X N/A N/A
SURPRISE X X X X X X X X N/A N/A
GOODWILL X X X X X X N/A N/A N/A N/A
STAMP_SURPRISE X X X X X X N/A N/A N/A N/A
GFR_SURPRISE N/A X X X X X N/A N/A N/A N/A
VISIT_BOOST N/A N/A N/A N/A N/A N/A N/A N/A X N/A
PARTNER_BMO X X X X X X N/A N/A N/A N/A
PARTNER_SURPRISE X X X X X X X N/A N/A N/A
WELCOME X X X X X X X X N/A N/A
POINT_CONDITIONAL X X X X X X X X N/A N/A
TARGETED_GAME_MASS N/A N/A N/A N/A N/A N/A N/A N/A N/A X
GAME_MASS N/A N/A N/A N/A N/A N/A N/A N/A N/A X
POWER_UP N/A N/A X X X X N/A N/A N/A N/A

Sample request

curl --location 'https://offermanagementapis-qa.azurewebsites.net/api/v1/offers/submit' \
--header 'Authorization: Bearer ***' \
--header 'countryCode: GB' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
  "acceptanceRequired": true,
  "accumulative": false,
  "assignableFrom": "2023-12-01",
  "assignableTo": "2023-12-02",
  "costOfReward": 12.25,
  "customText": [
    {
      "language": "en",
      "text": "Fill min 1L of any fuel and get 200 pts."
    }
  ],
  "deactivationAllowed": true,
  "displayOrder": 20,
  "expirationDays": 30,
  "expirationDaysAchievement": 30,
  "gameDetails": {
    "campaignOverviewImage": "82dc5ab1-1ceb-5cfe-b100-8cdfa4b306a6",
    "gameDescription": [
      {
        "language": "en",
        "text": "Play every day and get 200 points."
      }
    ],
    "gameIcon": "1234567890",
    "gameTANDCURL": "http://www.example.com/terms",
    "gameType": "Luck Game",
    "gameURL": "http://www.example.com",
    "inviteDurationDays": 100,
    "prizeDescription": [
      {
        "language": "en",
        "text": "This a prize description."
      }
    ]
  },
  "initiallyActive": true,
  "isDefault": false,
  "numberOfAssign": 3,
  "numberOfUsage": 0,
  "offerAchievementRule": [
    {
      "achievementRuleType": "PRODUCT_PURCHASE",
      "excludeProducts": [
        "CG0000000163"
      ],
      "includeProducts": [
        "CG0000000123"
      ],
      "label": "Rule 1",
      "progressIncrement": 100,
      "requiredQuantity": 50,
      "requiredTransactions": 10
    }
  ],
  "offerBackground": "82dc5ab1-1ceb-5cfe-b100-8cdfa4b306a6",
  "offerCode": "1234567890",
  "offerDescription": [
    {
      "language": "en",
      "text": "Fill min 1L of any fuel and get 200 pts."
    }
  ],
  "offerName": "New offer",
  "offerReceiptMessage": [
    {
      "language": "en",
      "text": "Fill min 1L of any fuel and get 200 pts"
    }
  ],
  "offerResetDay": 12,
  "offerRewardConditionRule": [
    {
      "conditionRuleType": "SPENT_AMOUNT",
      "productCode": "CG0000000163",
      "requiredValue": 12.5
    }
  ],
  "offerRewardRule": {
    "productCode": "CG0000000163",
    "rewardIncrement": 1000,
    "rewardLimit": 1000.5,
    "rewardValue": 100.5,
    "rounding": "UP",
    "ruleType": "FREE_PRODUCT"
  },
  "offerSubType": "GIVEAWAY",
  "offerTitle": [
    {
      "language": "en",
      "text": "10% discount on Shell Helix"
    }
  ],
  "offerType": "BASIC_MASS",
  "partialRewardOffer": false,
  "partnerCode": "RAC",
  "partnerFundingPercentage": 12.5,
  "partnerPointsValue": 10.5,
  "qualifyingVisitTarget": 10,
  "replacedOfferCode": 100,
  "requiredStamp": 10,
  "retailSite": "82dc5ab1-1ceb-5cfe-b100-8cdfa4b306a6",
  "rewardEngineExcluded": true,
  "validityLimitation": "Every Friday",
  "validityStartOffset": 15,
  "visibleFrom": "2023-12-01"
}'

After creating the offer, the offer will be sent to LOD. When LOD has processed it, the offer will be sent to Adobe.

Response

On success the response will have a 201 Created status and the body of the response will contain a simple JSON object with:

KEY NULLABLE VALUE TYPE DESCRIPTION
offerCode No String Code of the new offer.
offerId No String Unique identifier of the new offer.
status No String Status of the new offer. Can be one of the following values:
- Draft
- Approved
- Sent to loyalty
- Loaded to loyalty
- Failed to load in loyalty
- Loaded to campaign
- Failed to load in campaign
- Expired

Sample Response

{
  "offerCode": "test",
  "offerId": 12,
  "status": "Draft"
}

Exception Handling

The format of errors is always the same and specified in the Fundamentals section. For this endpoint, this is the list of possible errors:

HTTP CODE Description Scenarios/Use case
400 Bad Request Json format is not valid.
401 Unauthorized The user token is not valid anymore or missing.
403 Forbidden The user does not have permissions to do this action.
422 Unprocessable Content Mandatory fields are missing.

Assign an offer to a customer

This endpoint of the Offer Submission API https://offermanagementapis-qa.azurewebsites.net/api/v1/offers/{offerId}/assign uses the HTTP POST method.

Headers parameters

HEADER PARAMETER DATA TYPE LIMITS (MIN/MAX) NULLABLE DESCRIPTION
Authorization String N/A No This is a Bearer token. It should be the JWT token you got when you requested an Access Token before.

Example: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Path parameters

PATH PARAMETER DATA TYPE LIMITS (MIN/MAX) NULLABLE DESCRIPTION
offerId Number (integer) N/A No This is the offer id you want to assign to a customer.

Example: 123

Request body parameters

REQUEST BODY PARAMETER DATA TYPE LIMITS (MIN/MAX) NULLABLE DESCRIPTION
consumerUUID String N/A No The consumer you want to assign the offer.

Example: 942a1fb4-d487-454c-9c1c-aee920c420fb
validFrom DateTime Cannot be a past date. No Offer validity start date in JSON recommended format: yyyy-MM-ddTHH:mm:ssZ. The date format must follow ISO_8601.

It is the date from which the offer becomes available to the customer.

Example: 2023-08-24T14:15:22Z
validTo DateTime Cannot be a date before validFrom. No, when validityPeriod=0.
Yes, if validityPeriod!=0.
Offer validity start date in JSON recommended format: yyyy-MM-ddTHH:mm:ssZ. The date format must follow ISO_8601.

It is the date until which the offer is available to the customer.

Example: 2023-12-24T14:15:22Z
validityPeriod Number (integer) N/A No, when validTo is null.
Yes, if validTo is not null.
This is the number of days for which the assignment is valid after validFrom. It's optional if validTo is set and required otherwise. If not set, LOD will receive the default value of 0. validTo is calculating adding this value to the validFrom date.

If both validTo and validityPeriod are present, validityPeriod has priority over validTo.

Example: 31

Sample Request

curl --location 'https://offermanagementapis-qa.azurewebsites.net/api/v1/offers/123/assign' \
--header 'Authorization: Bearer ***' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
  "consumerUUID": "942a1fb4-d487-454c-9c1c-aee920c420fb",
  "validFrom": "2023-08-24T14:15:22Z",
  "validTo": "2023-12-24T14:15:22Z",
  "validityPeriod": 31
}'

Response

On success the response will have a 200 OK status and the body of the response will contain a simple JSON object with:

KEY NULLABLE VALUE TYPE DESCRIPTION
consumerUUUID No String The unique identifier of the consumer.
description No String Description of the offer.
offerID No Number (integer) The id of the offer.
referenceID No String The unique identifier of the offer.
responseCode No Number (integer) The response code from LOD. 200 if the offer was assigned inmediately. 202 if LOD is using an internal async process to assign it.
title No String The title of the offer.
validFrom No DateTime The date and time from which the offer becomes available to the customer.
validTo No DateTime The date and time until which the offer is available to the customer.

Sample Response

{
  "consumerUUID": "01bbf258-04f1-4ffc-be07-09a5ad5849de",
  "description": "",
  "offerID": 123,
  "referenceID": "85f09c39-8a5b-4f22-9a1e-d89656e6017c",
  "responseCode": 200,
  "title": "Offer",
  "validFrom": "2019-08-24T14:15:22Z",
  "validTo": "2019-08-24T14:15:22Z"
}

Exception Handling

The format of errors is always the same and specified in the Fundamentals section. For this endpoint, this is the list of errors:

HTTP CODE Description Scenarios/Use case
400 Bad Request Json format is not valid.
401 Unauthorized The user token is not valid anymore or missing.
403 Forbidden The user does not have permissions to do this action.
404 Not found The offer was not found using the offerId provided.
422 Unprocessable Content Mandatory fields are missing.

A propos de nous

Le portail des développeurs Shell aide les partenaires à se familiariser avec les API Shell et à transformer leurs idées en solutions prêtes à être mises en production.

Logo Shell

Contact

Connectez-vous à votre compte

Demandez à l'assistant IA des informations sur les API Shell et les produits API