NAV

Introduction

Welcome to the MyRewards API documentation.

Your 360insights project manager / customer success manager will share the API authentication details for your production site.

If you require a separate instance for testing and development purposes, please discuss this requirement with your 360insights project manager / customer success manager.

Access to the development build of MyRewards for upcoming features will only be granted on a discretionary basis.

A programme can have one or more API keys, each of which will be granted permission to access different functionality from the API. As a standard, we use RESTful json endpoints that will accept either HTML/HTTP form data or json data.

Authentication

Token

In order to use our API endpoints, you will need to have an API key created and for this key to be granted the relevant permissions. To authenticate requests we require you to pass us this key in the form of an HTTP header called Authorization with the value set as Token token={APIKEY} or Token token={APIKEY}:{SECRETKEY}.

Authentication

An API key now requires permissions to be assigned in order make any requests to the API. The issuer of your key will set permissions for endpoints you expect to access. If you need to access more of the API or you believe your permissions are not correct (unexpected 403 responses) then contact your key issuer.

Getting read access (GET) to an API endpoint does not mean that you will also have any kind of write access (PUT, PATCH, POST) and vice versa - these are separate permissions.

Permissions are granted on a 'least privilege' basis in order to restrict access to the API functionality to just what is needed for a given use case i.e. user account provisioning or sales data integration etc.

Core

Permissions

Permissions are used to grant access to administrative and reporting areas of the programme. They are also used to manage user access and ordering rights

Get all Permissions

Header:

GET /api/v2/permissions HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

[
  {
    "id" : 6,
    "name" : "Enable log in",
    "hint" : "Enable log in",
    "resource_group_name" : "General"
  },
  {
    "id" : 11,
    "name" : "Order Rewards",
    "hint" : "User can order rewards if they have sufficient points available",
    "resource_group_name" : "Rewards module"
  }
]

This endpoint retrieves all permissions for the current stack

HTTP Request

GET /api/v2/permissions

Attributes

Attribute Type Info
id integer permission id
name string permission name
hint string permission hint
resource_group_name string parent resource group name

Registration Questions

Get all Registration Questions

Header:

GET /api/v2/registration_questions HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}

Response:

[
  {
    "id": 1234,
    "label": "text",
    "mandatory": "false",
    "field_type": "radio",
    "options": "text_1 text_2 text_3",
    "field_name" : "field_level",
    "free_text": "false"
  }
]

A simple endpoint will be created to fetch registration_questions for this programme (Again scoped by API key). This is potentially optional as a list of registration_question_ids could be provided, although this list will have to be managed and maintained carefully. Should any new mandatory fields be added to this list, it would require development on the client side of the API unless this list can be dynamically consulted via the api.

HTTP Request

GET /api/v2/registration_questions

Attributes

Attribute Type Info
id integer registration question identifier
label string label displayed on the form to the end user
mandatory boolean boolean if this question is mandatory for registration
field_type string options: [check_box, date_select, radio, select, text, user_group, linked_user]
options string options set for a choice question for check_box, select, or radio
field_name string the actual field name
free_text boolean

Registration Questions > List of Values

GET List of Values associated with a registration question

An endpoint to fetch the list of values associated with a registration question. Returns an array of values with their name and id.

Header:

GET /api/v2/registration_questions/{registration_question_id}/list_of_values HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}

Response:

[
  {
    "id": 1,
    "name": "List value 1"
  },
  {
    "id": 2,
    "name": "List value 2"
  }
]

HTTP Request

GET /api/v2/registration_questions/{registration_question_id}/list_of_values

Attributes

Attribute Type Info
id integer List value id
name string List value name

POST Create a new value on a list of values associated with a registration question

An endpoint to create a new list value for a registration question. On completion, returns an array of all values with their name and id.

Header:

POST /api/v2/registration_questions/{registration_question_id}/list_of_values HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Body:

{
    "name": "My new list value"
}

Response:

[
  {
    "id": 1,
    "name": "List value 1"
  },
  {
    "id": 2,
    "name": "List value 2"
  },
  {
    "id": 3,
    "name": "My new list value"
  }
]

HTTP Request

POST /api/v2/registration_questions/{registration_question_id}/list_of_values

Body Parameters
Parameter Type Description
name string the name of the new list value

Site Messages

Site message are either plain text or HTML messages that appear in a User's message page. When a user logs in they are notified of any unread messages via a pop-up (usually in the bottom right corner)

Create a Site Message

Header:

GET /api/v2/user/{user_id}/site_messages/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Body:

{
    "content": "Hello John. You have <strong>won a prize</strong>. Please visit the points area for more details."
}

Response:

{
  "id": 2,
  "user_id": 123,
  "content": "Hello John. You have <strong>won a prize</strong>. Please visit the points area for more details.",
  "created_at": "2016-03-18T02:20:02.000+00:00"
}

This endpoint creates a new site message for a user.

HTTP Request

POST /api/v2/users/{user_id}/site_messages

Request Parameters

URL Parameters
Parameter Type Description
user_id integer the ID of the user who will receive the message
Body Parameters
Parameter Type Description
content string the content of message

Get a Site Message

Header:

GET /api/v2/user/{user_id}/site_messages/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

{
  "id": 2,
  "user_id": 123,
  "content": "Hello John. You have <strong>won a prize</strong>. Please visit the points area for more details.",
  "created_at": "2016-03-18T02:20:02.000+00:00"
}

Retrieves a specific site message.

HTTP Request

GET /api/v2/users/{user_id}/site_messages/{id}

Request Parameters

Parameter Type Description
user_id integer The ID of the user
id integer The ID of the site message to retrieve

Get all Site Messages

Header:

GET /api/v2/user/{user_id}/site_messages HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

[
  {
    "id": 1,
    "user_id": 123,
    "content": "Hello John. You have <strong>won a prize</strong>. Please visit the points area for more details.",
    "created_at": "2016-03-18T02:20:02.000+00:00"
  },
  {
    "id": 2,
    "user_id": 123,
    "content": "Your Order is on it's way",
    "created_at": "2017-08-16T07:58:03.000+01:00"
  }
]

Retrieves all site messages for a user.

HTTP Request

GET /api/v2/users/{user_id}/site_messages

Request Parameters

Parameter Type Description
user_id integer The ID of the user

Transactions

Get all Transactions

This endpoint is designed to list all of a user’s transactions in json format. The points transactions will be debits and credits with a description field.

All transactions listed in the response will be ordered so as to have the most recent transaction last in the list.

Please remember that if a user transaction is performed on the MyRewards 2.0 platform since a request is made over the api – this balance will be out of date.

On the server side a check will be made that the user_id you are requesting is

That is to say that you can only retrieve transactions for users of your MyRewards Programme.

The remote_transaction_id is documented in the POST endpoint for creating transactions, this value is optional, therefore can be null

GET /api/v2/users/{user_id}/transactions HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
HTTP/1.1 200 OK
Content-Type: application/json

[
  {
    "id": 123,
    "user_id" : 123,
    "description" : "transactions",
    "value" : 100,
    "balance" : 100,
    "transaction_type" : "programme points",
    "remote_transaction_id": "your_id_here",
    "created_at" : "date_time"
  }
]

HTTP Request

GET /api/v2/users/{user_id}/transactions

Attributes

Parameters Type Info
id integer id of this transaction
user_id integer user id of the user this transaction belongs
description string transaction description
value integer can be positive or negative. value of points on the transaction. Credit to the balance will be shown as a positive integer and debits will be negative
balance integer users running balance, at the time of the transaction
transaction_type string indicates the event which caused the transaction
remote_transaction_id integer optional - indicates a remote systems unique identifier for this transaction
created_at string

Get last Transaction

This endpoint is designed to show the latest transaction for the given user in json format. You can use this endpoint to find the user's current balance.

Please remember that if a user transaction is performed on the MyRewards 2.0 platform since a request is made over the api – this balance will be out of date.

On the server side a check will be made that the user_id you are requesting is

That is to say that you can only retrieve the last transaction for users of your MyRewards Programme.

The remote_transaction_id is documented in the POST endpoint for creating transactions, this value is optional, therefore can be null

GET /api/v2/users/{user_id}/transactions/last HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 123,
  "user_id" : 123,
  "description" : "transactions",
  "value" : 100,
  "balance" : 100,
  "transaction_type" : "programme points",
  "remote_transaction_id": "your_id_here",
  "created_at" : "date_time"
}

HTTP Request

GET /api/v2/users/{user_id}/transactions/last

Attributes

Parameters Type Info
id integer id of this transaction
user_id integer user id of the user this transaction belongs
description string transaction description
value integer can be positive or negative. value of points on the transaction
balance integer users running balance, at the time of the transaction
transaction_type string indicates the event which caused the transaction
remote_transaction_id integer optional - indicates a remote systems unique identifier for this transaction
created_at string datetime indicating when this points transaction was created

Create a Transaction

Note this is 'v1' endpoint. This endpoint is for either crediting or debiting points for a user. This endpoint will respond with the MyRewards transaction id. Points transactions have a type of either 'Credit' or 'Debit'. A points transaction will also have a variety which will be one of:

Variety Programme Points affecting? Permitted Type
Programme points Yes Credit only
Points Error Yes Debit only
Person2Person transfer Yes Credit or debit (credit and debit must both be carried out for each user)
Adjustment Yes Credit or Debit
Account Closure Programme config dependant Debit only

Example below shows a transaction that will credit 100 points to a user debited from the programme balance. On the user's points statement a reason of 'Employee of the month' will be shown.

POST /api/v1/users/{user_id}/transactions HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
  "transaction":  {
    "transaction_type": "Credit",
    "variety": "Programme points",
    "points": 100,
    "reason": "Employee of the month",
    "remote_transaction_id": "YOUR_REMOTE_TRANSACTION_ID"
  }
}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 123
}

HTTP Request

POST /api/v1/users/{user_id}/transactions

Parameters

Parameters Type Info
transaction_type string one of 'Credit' or 'Debit'
variety string Required - see above table and ensure validity with transaction_type
points integer Required - always greater than 0
reason string Required - free text up to 250 characters to describe transaction - appears on user points statement
remote_transaction_id string Optional - a value that can be used to identify this transaction by the client Caution - there is no validation or constraints for data supplied under this key/field. This is left to the client system to enforce

Error responses

Anything other than a 200 will mean that the transaction has failed to go through. It may or may not be appropriate to show only a generic message to indicate failure depending on the use case or level of automation. In either case it is recommended to log the error code and any body/message

Error Code Meaning
204 No Content -- User not found
401 Unauthorized -- Your API key is wrong.
402 Forbidden -- User does not have enough points
406 Not Acceptable -- Invalid Transaction
412 Pre condition failed -- Programme does not have enough points and/or you have provided an invalid transaction type and variety combination.
500 Internal Server Error -- We had a problem with our server. Try again later.

User Groups

Get all User Groups

A simple endpoint to fetch a list of user groups used for this programme. Only accessible if the key has been granted access to users. Returns an array of user_groups as a flat list, each user group will indicate it's parent id enabling the client end of the API to re-construct the user group hierarchy. This would be required if a registration_question is linked to a tier of user_groups with a tier being a vertical 'slice' down the hierarchy

GET /api/v2/user_groups HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
HTTP/1.1 200 OK
Content-Type: application/json

[
    {
        "id": 1,
        "name": "Admin",
        "description": "Example Description",
        "parent_id": null,
        "default": "false",
        "position": 1
    },
    {
        "id": 5,
        "name": "Full-Time",
        "description": "Example Description",
        "parent_id": 1,
        "default": "true",
        "position": 2
    },
    {
        "id": 10,
        "name": "Part-Time",
        "description": "Another Example Description",
        "parent_id": 1,
        "default": "false",
        "position": 3
    }
]

HTTP Request

GET /api/v2/user_groups

Attributes

Attribute Type Info
id integer user_group id
name string user_group name
description string user_group description
parent_id integer parent user_group id
default boolean indicates if this user_group is the default group for the programme
position integer position under the parent user_group, used for ordering

Get a User Group

This endpoint returns a specific user group associated to an api keys programme.

Path Parameters

Parameter Type Description
user_group_id integer The ID of the user group you want to return

HTTP Request

GET /api/v2/user_groups/{user_group_id}

Request:

GET /api/v2/user_groups/{user_group_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

HTTP/1.1 200 OK
Content-Type: Application/json

{
    "id": 10,
    "name": "Part-Time",
    "description": "Another Example Description",
    "parent_id": 1,
    "default": "false",
    "position": 3
}

Create User Groups

An endpoint to create a user group for this programme. Only accessible if the key has been granted access to users. In order to create a usergroup a name is required. This usergroup can be nested underneath another user group by passing the parent user group id. Images can be uploaded to the user group by passing a publicly accessible image url. If no position is passed then it will default to the bottom of the hierachy.

POST /api/v2/user_groups HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}

{
    "name": "Contractors",
    "description": "Another Example Description",
    "parent_id": 1,
    "position": 4,
    "image_url": "http://example_website.com/image.png"
}
HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": "20",
    "name": "Contractors",
    "description": "Another Example Description",
    "programme": "Demo Programme",
    "parent_id": 1,
    "position": 4,
    "image_url": "http://example_website.com/image.png"
}

HTTP Request

POST /api/v2/user_groups

Parameters

Parameters Type Info
name string Required - name of the user_group to be created
description string description of the user_group, which is visible in the admin area only
position integer position of the user_group in the hierachy
parent_id integer an optional id field, used if this user group should be nested underneath another
image_url string a url of user group image

Update a User Group

This endpoint updates a specific user_group associated to an api keys programme. Please note that attempting to change a user_group's default, will result in an error.

Request:

PUT /api/v2/user_groups/{user_group_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "name": "Sub-Contractors",
    "position": 5
}

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": "20",
    "name": "Sub-Contractors",
    "description": "Another Example Description",
    "programme": "Demo Programme",
    "parent_id": 1,
    "position": 5,
    "image_url": "http://example_website.com/image.png"
}

HTTP Request

PUT /api/v2/user_groups/{user_group_id}

Attributes

Attribute Type Description
name string Name of the user_group
description string description of the user_group, which is visible in the admin area only
position integer Position of the user_group in the hierachy
parent_id integer ID of a user_group that this user_group should be nested underneath. Providing an invalid ID will result in an error.
image_url string A url of the user_group image

Delete a User Group

This endpoint deletes a specific user group associated to an api keys programme. You can only delete user groups that have no associated users or user groups, and are not the default user group. Any attempt to do so will result in an error.

Path Parameters

Parameter Type Description
user_group_id integer The ID of the user group you want to delete

HTTP Request

DELETE /api/v2/user_groups/{user_group_id}

Request:

DELETE /api/v2/user_groups/{user_group_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

HTTP/1.1 200 OK
No content

User Group > Permissions

GET UserGroup permissions

An endpoint to fetch a list of permissions for a given user_group. Returns an array of permissions with each permission displaying its parent permission group name. This is to help identify different permissions when names are the same across separate groups. It will also display whether the permission is active for a given user_group.

GET /api/v2/user_groups/{user_group_id}/permissions HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "permissions" : [
    {
      "id" : 1,
      "name" : "Enable log in",
      "permission_group_name" :  "General",
      "active" : false
    },
    {
      "id" : 2,
      "name" : "Order Rewards",
      "permission_group_name" :  "Rewards module",
      "active" : true
    }
  ]
}

HTTP Request

GET /api/v2/user_groups/{user_group_id}/permissions

Attributes

Attribute Type Info
id integer Required permission id
name string Required permission name
permission_group_name string Required parent permission group name
active string Required indicates if this permission is active for this user_group

Update a User Group's Permission set

An endpoint to update the permissions associated with a give user_group. After querying for the list of permissions associated with a given user_group, you can add or remove a permission by simply changing the value associated with the active key from true to false or vice-versa. You will be returned the updated list of permissions relative to the given user_group

N.B. If updating a permission where the permission_group is not active the change will be ignored

PATCH /api/v2/user_groups/{user_group_id}/permissions HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}

{
  "permissions" : [
    {
      "id" : 1,
      "name" : "Enable log in",
      "permission_group_name" :  "General",
      "active" : false
    },
    {
      "id" : 2,
      "name" : "Order Rewards",
      "permission_group_name" :  "Rewards module",
      "active" : false
    }
  ]
}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "permissions" : [
    {
      "id" : 1,
      "name" : "Enable log in",
      "permission_group_name" :  "General",
      "active" : false
    },
    {
      "id" : 2,
      "name" : "Order Rewards",
      "permission_group_name" :  "Rewards module",
      "active" : false
    }
  ]
}

HTTP Request

PATCH /api/v2/user_groups/{user_group_id}/permissions

Attributes

Attribute Type Info
id integer permission id
name string permission name
permission_group_name string parent permission group name
active string indicates if this permission is active for this user_group

Users

In order to identify users, a programme will expect to use either username, email or mobile as a unique key to authenticate users with. As a consumer of this service, it is mandatory to supply a value for this field. Furthermore, there will be other fields that have been declared mandatory for your programme and user creation (POST) could fail if these values are not populated or provided.

Reasons include:

Create a User

Request:

POST /api/v3/users HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "title": "Dr",
    "firstname": "John",
    "lastname": "Doe",
    "username": "john.doe",
    "email": "john.doe@email.null",
    "company": "Org Inc",
    "job_title": "Demo User",
    "address_1": "No 1 The Place",
    "address_2": "The Street",
    "town": "The Town",
    "county": "The County",
    "postcode": "TH3 P057",
    "country": "UK",
    "date_of_birth": "1970-01-01",
    "telephone": "+440000000000",
    "mobile": "+440000000000",
    "chosen_locale": "en",
    "user_group_id": "10",
    "tsandcs": "true",
    "consented": "false",
    "marketing_consented": "true",
    "registration_answers_attributes": [
        {
            "registration_question_id": "2",
            "answer": "Working From Home"
        },
        {
            "registration_question_id": "16",
            "answer": [
                "Monday",
                "Wednesday",
                "Friday"
            ]
        }
    ]
}

Response:

HTTP/1.1 201 CREATED
Content-Type: Application/json

{
    "id": 123,
    "title": "Dr",
    "firstname": "John",
    "lastname": "Doe",
    "username": "john.doe",
    "email": "john.doe@email.null",
    "company": "Org Inc",
    "job_title": "Demo User",
    "address_1": "No 1 The Place",
    "address_2": "The Street",
    "town": "The Town",
    "county": "The County",
    "postcode": "TH3 P057",
    "country": "UK",
    "date_of_birth": "1970-01-01",
    "telephone": "+440000000000",
    "mobile": "+440000000000",
    "chosen_locale": "en",
    "user_group_id": "10",
    "tsandcs": "true",
    "consented": "false",
    "marketing_consented": "true",
    "registration_answers_attributes": [
        {
            "registration_question_id": "2",
            "question": {
                "user_locale": "Workplace",
                "stack_locale": "Workplace"
            },
            "answer": "Working From Home"
        },
        {
            "registration_question_id": "16",
            "question": {
                "user_locale": "Work Days",
                "stack_locale": "Work Days"
            },
            "answer": [
                "Monday",
                "Wednesday",
                "Friday"
            ]
        }
    ]
}

In order to create a user account on the MyRewards 2.0 platform there is often some information about the user we are creating that needs to be known before the account can be successfully created.

User group

The user group that the user will be created as a member of must be known, we provide an endpoint to query the usergroups for your programme and if necessary to reconstruct the hierarchy for the usergroups see the usergroups section.

Phone numbers

Telephone and mobile number fields must be supplied in international format, meaning starting with a '+' followed by the international country code (I.e. the UK is 44) followed by at least 8 numeric characters.

Registration questions

User accounts can have extra data required over and above the minimal default fields for a user account. Typically, these take the form of employee data, membership number etc and can be defined as part of your programme. These extra data are called registration_questions, for more information please see the registration_questions section.

Answers to the registration questions are provided in an array of objects, nested under the key registration_answers_attributes. The nested objects themselves must have the keys registration_question_id and answer. If the question allows multiple answers, then the value for answer should be an array, as show in the example below.

Chosen Locale

When creating or updating a user, if the associated programme has locale marked as mandatory, chosen_locale must be provided. Failure to do so will result in an error. When locale is not mandatory and a chosen_locale value is not provided, the value will be set to the programme default locale.

Company

When providing a user's company, the value must match what is expected by the programme, i.e. if the company is a free-text field, then a string should be provided. If, however, the programme is using a managed list of companies, the value must be an object containing the name and identifier strings.

Example 1: Company as a free-text field:

"company": "Luther Corp"

Example 2: Company as a manage list:

"company": { "name": "Org Inc", "identifier": "org-inc-01" }

If the company can not be found, it will be created. Existing companies will have their name updated if different.

The response from the API will also differ depending whether the company is free-text or a managed list and will mirror the format sent in the request. The "Update a user" below shows an example of the response when the company is a managed list.

To unset company, pass null as shown below:

"company": null

HTTP Request

POST /api/v3/users

Parameters

Parameters Type Info
username string may be required, see user identification above, must be unique to the programme if required
email string valid email address and may be required, see user identification above, must be unique to the programme if required
title string salutation (Mr, Mrs, Ms, etc) no strict validation.
firstname string Required
lastname string Required
company mixed Potentially required - see programme data requirements. Should be a string or an object - see "Company" section above.
job_title string Potentially required - see programme data requirements
address_1 string Potentially required - see programme data requirements
address_2 string optional
town string Potentially required - see programme data requirements
postcode string Potentially required - see programme data requirements
county string Potentially required - see programme data requirements
country string Potentially required - see programme data requirements
date_of_birth date must be provided in reverse date format YYYY-MM-DD, Potentially required - see programme data requirements
telephone string Potentially required - see programme data requirements - if supplied must be international format (starting with a '+' followed by international dialling code - UK is 44 - followed by at least 8 numeric characters)
mobile string Potentially required - see programme data requirements, if required, must be unique - if supplied must be international format (starting with a '+' followed by international dialling code - UK is 44 - followed by at least 8 numeric characters)
chosen_locale string Potentially required - see programme data requirements.
tsandcs boolean Required
user_group_id integer optional, will default to programme's default user_group, if not provided
registration_answers_attributes array array of hashes that contain a registration_question_id and an answer. Some or all of the registration questions may require answers. See registration_questions endpoint documentation
consented boolean Not required if programme access type is pre_registration with additional details, or SSO or if the programme doesn't have an active privacy policy.
marketing_consented boolean Can be true or false, not required if programme access type is pre_registration with additional details, or SSO or if the programme doesn't have an active privacy policy.

Get a User

This endpoint returns a specific user associated with an api key's programme. You have the option to specify either the user's unique MyRewards ID, email address, or the username.

Path Parameters

Parameter Type Description
id integer The unique MyRewards ID of the user to return
email string The email address of the user to return
username string The username of the user to return

HTTP Request

variations of the request that are supported:

Request:

GET /api/v3/users/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

HTTP/1.1 200 OK
Content-Type: Application/json

{
    "id": 123,
    "title": "Dr",
    "firstname": "John",
    "lastname": "Doe",
    "username": "john.doe",
    "email": "john.doe@email.null",
    "company": "Org Inc",
    "job_title": "Demo User",
    "address_1": "No 1 The Place",
    "address_2": "The Street",
    "town": "The Town",
    "county": "The County",
    "postcode": "TH3 P057",
    "country": "UK",
    "date_of_birth": "1970-01-01",
    "telephone": "+440000000000",
    "mobile": "+440000000000",
    "chosen_locale": "en",
    "user_group_id": "10",
    "tsandcs": "true",
    "consented": "false",
    "marketing_consented": "true",
    "registration_answers_attributes": [
        {
            "registration_question_id": "2",
            "question": {
                "user_locale": "Workplace",
                "stack_locale": "Workplace"
            },
            "answer": "Working From Home"
        },
        {
            "registration_question_id": "16",
            "question": {
                "user_locale": "Work Days",
                "stack_locale": "Work Days"
            },
            "answer": [
                "Monday",
                "Wednesday",
                "Friday"
            ]
        }
    ]
}

Update a User

Request:

PUT /api/v3/users/{user_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "user_group_id": "5",
    "registration_answers_attributes": [
        {
            "registration_question_id": "2",
            "answer": "Office"
        },
        {
            "registration_question_id": "16",
            "answer": [
                "Monday",
                "Tuesday",
                "Wednesday",
                "Thursday",
                "Friday"
            ]
        }
    ]
}

Response:

HTTP/1.1 200 OK
Content-Type: Application/json

{
    "id": 123,
    "title": "Dr",
    "firstname": "John",
    "lastname": "Doe",
    "username": "john.doe",
    "email": "john.doe@email.null",
    "company": "Org Inc",
    "job_title": "Demo User",
    "address_1": "No 1 The Place",
    "address_2": "The Street",
    "town": "The Town",
    "county": "The County",
    "postcode": "TH3 P057",
    "country": "UK",
    "date_of_birth": "1970-01-01",
    "telephone": "+440000000000",
    "mobile": "+440000000000",
    "chosen_locale": "en",
    "user_group_id": "5",
    "tsandcs": "true",
    "consented": "false",
    "marketing_consented": "true",
    "registration_answers_attributes": [
        {
            "registration_question_id": "2",
            "question": {
                "user_locale": "Workplace",
                "stack_locale": "Workplace"
            },
            "answer": "Office"
        },
        {
            "registration_question_id": "16",
            "question": {
                "user_locale": "Work Days",
                "stack_locale": "Work Days"
            },
            "answer": [
                "Monday",
                "Tuesday",
                "Wednesday",
                "Thursday",
                "Friday"
            ]
        }
    ]
}

The update user api is available to update user information. This uses the same params as the create user api above.

HTTP Request

PUT /api/v3/users/{user_id}

PATCH /api/v3/users/{user_id}

User > Permissions

GET User permissions

An endpoint to fetch a list of permissions for a given user. Returns an array of permissions displaying it's parent permissions group name. This is to help identify different permissions when names are the same across separate groups. It will also display whether the permission is active for the given user and the state of the permission which can be Same As User Group or if the permission has been overridden for that user: Always Allow or Always Deny.

GET /api/v2/users/{user_id}/permissions HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "permissions" : [
    {
      "id" : 1,
      "name" : "Enable log in",
      "permission_group_name" :  "General",
      "active" : false,
      "state" : "Same As User Group"
    },
    {
      "id" : 2,
      "name" : "Order Rewards",
      "permission_group_name" :  "Rewards module",
      "active" : true,
      "state" : "Always Allow"
    }
  ]
}

HTTP Request

GET /api/v2/users/{user_id}/permissions

Attributes

Attribute Type Info
id integer Required permission id
name string Required permission name
permission_group_name string Required parent permission group name
active string Required indicates if this permission is active for this user
state string Required indicates whether the permission is granted or denied specifically for this user or if it is the same as the user_group

POST User permissions

A endpoint to update a list of permissions for a given user. Returns an array of permissions displaying it's parent permissions group name. This is to help identify different permissions when names are the same across separate groups. It will also display whether the permission is active for the given user and the state of the permission which can be Same As User Group or if the permission has been overridden for that user: Always Allow or Always Deny.

The only value that this request will change is the active field. The other fields are present to make it easier to move from the GET request to a POST without having to reformat or delete much of the GET request response.

N.B. When specifying active = true this will set the permission to "Always allow" setting to false will have the effect of "Always deny"

PATCH /api/v2/users/{user_id}/permissions HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}

{
  "permissions" : [
    {
      "id" : 1,
      "name" : "Enable log in",
      "permission_group_name" :  "General",
      "active" : true
    },
    {
      "id" : 2,
      "name" : "Order Rewards",
      "permission_group_name" :  "Rewards module",
      "active" : false
    }
  ]
}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "permissions" : [
    {
      "id" : 1,
      "name" : "Enable log in",
      "permission_group_name" :  "General",
      "active" : true
    },
    {
      "id" : 2,
      "name" : "Order Rewards",
      "permission_group_name" :  "Rewards module",
      "active" : false
    }
  ]
}

HTTP Request

PATCH /api/v2/users/{user_id}/permissions

Attributes

Attribute Type Info
id integer Required permission id
name string Required permission name
permission_group_name string Required parent permission group name
active string Required indicates if this permission is active for this user

Companies

Get all companies

This endpoint returns all companies associated to an api keys programme. Results are paginated and return 100 records per page and can be paged through by passing a page query parameter. If no page parameter is passed, then page 1 with the first 100 records will be returned.

HTTP Request

GET /api/v3/companies

Query Parameters

Parameter Type Description
page integer The page number that you wish to view

Request:

GET /api/v3/companies?page=1 HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

HTTP/1.1 200 OK
Content-Type: Application/json

[
  {
    "id": 1423,
    "name" : "Company A",
    "identifier" : "company-a-identifier",
    "disabled" : false,
    "earning_type" : "individual",
    "created_at" : "2021-03-18T02:20:02.000+00:00",
    "updated_at" : "2021-03-19T03:20:09.000+00:00",
  },
  {
    "id": 1477,
    "name" : "Company B",
    "identifier" : "company-b-identifier",
    "disabled" : true,
    "earning_type" : "company",
    "created_at" : "2021-03-18T02:20:06.000+00:00",
    "updated_at" : "2021-03-20T13:42:17.000+00:00",
  }
]

Get a specific company

This endpoint returns a specific company associated to an api keys programme.

Path Parameters

Parameter Type Description
company_identifier string The identifier of the company you want to return

HTTP Request

GET /api/v3/companies/{company_identifier}

Request:

GET /api/v3/companies/company-b-identifier HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

HTTP/1.1 200 OK
Content-Type: Application/json

{
  "id": 1477,
  "name" : "Company B",
  "identifier" : "company-b-identifier",
  "disabled" : true,
  "earning_type" : "company",
  "created_at" : "2021-03-18T02:20:06.000+00:00",
  "updated_at" : "2021-03-20T13:42:17.000+00:00",
}

Create a company

This endpoint creates a new company associated to an api keys programme.

HTTP Request

POST /api/v3/companies

Request:

POST /api/v3/companies HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "name": "Company name",
    "identifier": "company-identifier",
    "disabled": "N",
    "earning_type": "company"
}

Response:

HTTP/1.1 200 OK
Content-Type: Application/json

{
  "id": 123,
  "name": "Company name",
  "identifier": "company-identifier",
  "disabled": false,
  "earning_type": "company",
  "created_at": "2021-03-18T02:20:06.000+00:00",
  "updated_at": "2021-03-18T02:20:06.000+00:00"
}

Attributes

Attribute Type Info
name string Mandatory. The name of the company.
identifier string Mandatory. The unique identifier for the company.
disabled string Mandatory. The disabled status of the company. One of 'Y' for disabled or 'N' for not disabled.
earning_type string Optional. The earning type of the company. Must be one of 'individual' or 'company'. If not provided, company will be set with the 'individual' earning type.

Update a company

This endpoint updates an existing company associated to an api keys programme.

HTTP Request

PATCH /api/v3/companies/{company_id}

Request:

PATCH /api/v3/companies/{company_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "name": "New company name",
    "identifier": "new-company-identifier",
    "disabled": "Y",
    "earning_type": "individual"
}

Response:

HTTP/1.1 200 OK
Content-Type: Application/json

{
  "id": 123,
  "name": "New company name",
  "identifier": "new-company-identifier",
  "disabled": true,
  "earning_type": "individual",
  "created_at": "2021-03-18T02:20:06.000+00:00",
  "updated_at": "2021-03-20T13:42:17.000+00:00",
}

Attributes

Attribute Type Info
name string The name of the company.
identifier string The unique identifier for the company.
disabled string The disabled status of the company. One of 'Y' for disabled or 'N' for not disabled.
earning_type string The earning type of the company. Must be one of 'individual' or 'company'.

Delete a company

This endpoint deletes an existing company associated to an api keys programme. You can only delete companies that have no associated users, and any attempt to do so will return an error.

HTTP Request

DELETE /api/v3/companies/{company_id}

Request:

DELETE /api/v3/companies/{company_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

HTTP/1.1 204 No Content
Content-Type: Application/json

URL Parameters

Parameter Description
company_id The ID of the company to delete

Extra Features

Data Widgets

A Data Widget is used to show user specific information or data uploaded into the data widgets area.

Get all Data Widgets

Header:

GET /api/v2/data_widgets HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

[
  {
    "id": 1234,
    "name": "text"
  },
  {
    "id": 4567,
    "name": "some other text"
  }
]

This endpoint retrieves all data_widgets that belong to a programme (scoped by api key)

HTTP Request

GET /api/v2/data_widgets

Get a Data Widget belonging to a User

Header:

GET /api/v2/users/{user_id}/data_widgets/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response

{
    "id": 456,
    "name": "Data widget name",
    "user_data_widget": {
        "user_id": 123,
        "data": "this is some text"
    }
}

Returns the specific data_widget & user_data_widget data for the user specified { user_id } and the { id } specified.

HTTP Request

GET api/v2/users/{user_id}/data_widgets/{id}

Parameters

Parameter Type Description
user_id integer The ID of the user you want to retrieve data for
id integer The ID of the data_widget to retrieve

Update a Data Widget belonging to a User

Header:

PUT /api/v2/users/{user_id}/data_widgets/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Body:

{
  "data": "this is some new text"
}

Response:

{
    "id": 456,
    "name": "Data widget name",
    "user_data_widget": {
        "user_id": 123,
        "data": "this is some new text"
    }
}

Update the data of the specific user_data_widget for the user specified { user_id } and the { id } specified.

HTTP Request

PUT api/v2/users/{user_id}/data_widgets/{id}

Parameters

Parameter Type Description
user_id integer The ID of the user you want to update data for
id integer The ID of the data_widget to retrieve
data string Your desired data string

Target Trackers

A target tracker is used to display a target value to a user and their achievement against that target.

Get All Target Trackers

Header:

GET /api/v2/target_trackers HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json
[
  {
    "id": 1234,
    "name": "text"
    "currency": "points"
  },
  {
    "id": 4567,
    "name": "some other text"
    "currency": "£"
  }
]

This endpoint retrieves all target_trackers that belong to a programme (scoped by api key)

HTTP Request

GET /api/v2/target_trackers

Get a Target Tracker's values belonging to a User

Header:

GET /api/v2/users/{user_id}/target_trackers/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response

{
  "id": 456,
  "name": "Team",
  "target_tracker_users": {
    "user_id": 123,
    "target_value": 2000.00,
    "current_value": 1000.00
   }
}

Returns the specific target_tracker & target_tracker_user data for the { user_id } and { id } specified.

HTTP Request

GET api/v2/users/{user_id}/target_trackers/{id}

Parameters

Parameter Type Description
user_id integer The ID of the user you want to retrieve target_tracker data for
id integer The ID of the target_tracker to retrieve

Update a Target Tracker belonging to a User

Header:

PUT /api/v2/users/{user_id}/target_trackers/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Body:

{
  "target_value": 2000.00,
  "current_value": 1000.00
}

Response

{
  "id": 456,
  "name": "Team",
  "target_tracker_users": {
    "user_id": 123,
    "target_value": 2000.00,
    "current_value": 1000.00
  }
}

Update the attributes of the specific target_tracker_user for the specified { user_id } and the { id }.

HTTP Request

PUT api/v2/users/{user_id}/target_trackers/{id}

Parameters

Parameter Type Description
user_id integer The ID of the user you want to update target_tracker_user data for
id integer The ID of the target_tracker to retrieve
target_value float Your desired target_value
current_value float Your desired current_value

Badges

GET User Badges

An endpoint to fetch a list of badges for a given user.

GET /api/v2/users/{user_id}/badges HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
HTTP/1.1 200 OK
Content-Type: application/json

[
  {
    "id": 12,
    "badge_name": "Log In",
    "badge_collection_name": "Apprentice",
    "badge_won": true,
    "awarded_at": "2017-07-04T16:41:30.000+01:00",
    "updated_at": "2017-07-04T16:42:13.000+01:00"
  },
  {
    "id": 11,
    "badge_name": "E-Learning Test",
    "badge_collection_name": "Apprentice",
    "badge_won": false,
    "awarded_at": "2017-07-04T16:34:34.000+01:00",
    "updated_at": "2017-07-04T17:15:10.000+01:00"
  }
]

HTTP Request

GET /api/v2/users/{user_id}/badges

Request Parameters

Parameter Type Description
user_id integer The ID of the user

PUT User Badge

A endpoint to update a badge for a given user.

PUT /api/v2/users/{user_id}/badges/{badge_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
{
  "badge_won": "true"
}
HTTP/1.1 200 OK
Content-Type: application/json

  {
    "id": 11,
    "badge_name": "E-Learning Test",
    "badge_collection_name": "Apprentice",
    "badge_won": true,
    "awarded_at": "2017-07-04T16:34:34.000+01:00",
    "updated_at": "2017-07-04T17:15:10.000+01:00"
  }

HTTP Request

PUT /api/v2/users/{user_id}/badges/{badge_id}

URL Parameters

Parameter Type Description
id integer Required badge id
user_id integer The ID of the user

Body Parameters

Attribute Type Info
badge_won string Required badge won status

Performance Module

Allocated Claims

View Allocated Claims

Endpoint to view allocated claims against a specific promotion. Claims can be scoped down via passed in parameters. Only 100 records are returned at a time.

GET /api/v2/performance/promotions/{promotion_id}/allocated_claims HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
  "user_group_id": 1,
  "company_id": 1,
  "status": "pending",
  "created_at_start_date": "01/01/2020",
  "created_at_end_date": "02/02/2020",
  "date_of_sale_start_date": "01/01/2020",
  "date_of_sale_end_date": "02/02/2020"
}
HTTP/1.1 200 Ok
Content-Type: application/json

{
  "allocated_claims":
    [
        {
            "id": 1,
            "sale_date": "01/02/2018",
            "product_or_activity_ref": "AAA1234",
            "quantity": 2,
            "user_group_id": 2,
            "company_id": 5,
            "company_name": "Company C",
            "company_identifier": "company799988",
            "status": "pending",
            "created_at": "01/02/2018",
            "some_custom_field": "some custom answer"
        },
        {
            "id": 2,
            "sale_date": "01/02/2018",
            "product_or_activity_ref": "AAA1234",
            "quantity": 1,
            "user_group_id": 2,
            "company_id": 5,
            "company_name": "Company C",
            "company_identifier": "company799988",
            "status": "pending",
            "created_at": "01/02/2018",
            "some_custom_field": "another custom answer"
        }
    ]
}

HTTP Request

GET /api/v2/performance/promotions/{promotion_id}/allocated_claims

Attributes

Attribute Type Info
promotion_id integer The ID of the promotion claim is for. Mandatory.
user_group_id integer ID of a user_group that allocated_claims belong to, used for scoping down results. Optional
company_id integer ID of a company that allocated_claims belong to, used for scoping down results. Optional
status string Required Status for the allocated_claims that are returned, used for scoping down results. Optional
created_at_start_date string A parameter for scoping allocated_claims that were created from that date onwards. Optional.
created_at_end_date string A parameter for scoping allocated_claims that were created before the given date. Optional.
date_of_sale_start_date string A parameter for scoping allocated_claims with a date_of_sale from the given date onwards. Optional.
date_of_sale_end_date string A parameter for scoping allocated_claims with a date_of_sale before the given date. Optional.
page integer The requested page number. Defaults to page 1 if not supplied. Optional.

Decline Allocated Claims

Endpoint to decline a given allocated claim.

POST /api/v2/performance/promotions/{promotion_id}/allocated_claims/{claim_id}/decline HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
  "reason_for_decline_id": "An id for a decline reason",
  "reason_for_decline_text": "Some reason text string"
}
HTTP/1.1 201 Created
Content-Type: application/json

HTTP Request

POST /api/v2/performance/promotions/{promotion_id}/allocated_claims/{claim_id}/decline

Attributes

Attribute Type Info
reason_for_decline_id string The ID of a reason belonging to the promotion. Mandatory if decline reasons enabled on programme.
reason_for_decline_text string A text string for a decline reason, can only be provided if the promotion allows free text decline reasons. Optional.

Create Allocated Claims

Endpoint to create allocated claims against specific promotion. Claims are created by using the data_field names from above as key/value pairs. Your request must include exactly one of user_group_id or company_id or company_identifier depending on the promotion configuration.

POST /api/v2/performance/promotions/{promotion_id}/allocated_claims HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
  "allocated_claims":
    [
        {
            "sale_date": "01/02/2018",
            "product_or_activity_ref": "AAA1234",
            "quantity": 2,
            "user_group_id": 2,
            "company_id": 5,
            "company_identifier": "company799988",
            "some_custom_field": "some custom answer"
        },
        {
            "sale_date": "03/12/2017",
            "product_or_activity_ref": "BBB4567",
            "quantity": 1,
            "user_group_id": 5,
            "company_id": 3,
            "company_identifier": "company3466563",
            "some_other_custom_field": "some other custom answer"
        }
    ]
}
HTTP/1.1 201 Created
Content-Type: application/json

{
  "allocated_claims":
    [
        {
            "id": 1,
            "sale_date": "01/02/2018",
            "product_or_activity_ref": "AAA1234",
            "quantity": 2,
            "user_group_id": 2,
            "company_id": 5,
            "company_name": "Company C",
            "company_identifier": "company799988",
            "some_custom_field": "some custom answer"
        },
        {
            "id": 2,
            "sale_date": "03/12/2017",
            "product_or_activity_ref": "BBB4567",
            "quantity": 1,
            "user_group_id": 5,
            "company_id": 3,
            "company_name": "Company B",
            "company_identifier": "company3466563",
            "some_other_custom_field": "some other custom answer"
        }
    ]
}

HTTP Request

POST /api/v2/performance/promotions/{promotion_id}/allocated_claims

Attributes

Attribute Type Info
promotion_id integer The ID of the promotion claim is for.
sale_date date The date when this piece of data was created. Mandatory.
product_or_activity_ref string The SKU for the performance product to claim against
quantity integer The quantity of products sold. Mandatory.
user_group_id integer ID of the user group claim relates to (exactly one of user_group_id, company_id, or company_identifier needs to be supplied)
company_id integer ID of the MyRewards company claim related to (exactly one of user_group_id, company_id, or company_identifier needs to be supplied)
company_identifier string Identifier of the MyRewards company claim related to (exactly one of user_group_id, company_id, or company_identifier needs to be supplied)

You will also need to provide any custom data fields as extra keys for each piece of claim data in snake case format which is provided in the name field for the GET List Data Fields for a Promotion.

Eg:

Attribute Type Info
some_custom_field custom field type A custom answer for this field

Self Claims

Create a Self Claim

Endpoint to create a self claim against a specific self-claim promotion.

HTTP Request

POST /api/v2/performance/promotions/{promotion_id}/self_claims

Header:

POST /api/v2/performance/promotions/{promotion_id}/self_claims HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Body:

{
  "user_id": 1,
  "sale_date": "2022-01-29",
  "product_or_activity_ref": "p1",
  "quantity": 150,
  "answers": {
    "1": "Free text answer",
    "2": "2017-06-21",
    "3": "abcdefg",
    "4": "Choice A, Choice B",
    "5": "https://invoicefile/12353.doc"
  }
}

Response:

{
  "id": 1234,
  "user_id": 1,
  "sale_date": "2022-01-29",
  "product_or_activity_ref": "p1",
  "quantity": 150,
  "answers": {
    "1": {
        "question": "dynamic question free text?",
        "answer": "Free text answer"
    },
    "2": {
        "question": "dynamic question date select",
        "answer": "2017-06-21"
    },
    "3": {
        "question": "dynamic question scanner",
        "answer": "abcdefg"
    },
    "4": {
        "question": "dynamic question list",
        "answer": "Choice A, Choice B"
    },
    "5": {
        "question": "dynamic question file upload",
        "answer": "https://invoicefile/12353.doc"
    }
  }
}

Request Parameters

Body Parameters
Parameter Type Description
user_id integer The user ID of the user making the claim. Mandatory.
sale_date string The date the product was sold. Mandatory
product_or_activity_ref string The reference of the product or activity you wish to return claims for. Mandatory.
quantity integer The quantity of products sold. Mandatory.
answers string Expected answers depend on their question, which come in the following types: free text, list of values, date select, file upload, scanner. Please provide your answers to dynamic questions as a question_id to answer hash, nested under an answers key. If the question allows multiple answers, add a comma between each answer. Dynamic questions are sometimes mandatory (if the programme administrator has set them to be).

Response Attributes

Attribute Type Info
id integer the id of the claim
user_id string The user ID of the user making the claim.
sale_date string The date the product was sold.
product_or_activity_ref string The reference of the claimed product or activity.
quantity integer The quantity of products sold.
answers object An object containing questions identified by their id, along with a child object containing the name of the question, and the answer provided for that question.

Get Self Claims

Endpoint to get self claims against a specific self-claim promotion. Claims can be filtered down via passed-in parameters. If no URL parameters are provided then all claims against the requested promotion are returned. Results are paginated at 100 records per page.

HTTP Request

GET /api/v2/performance/promotions/{promotion_id}/self_claims

Header:

GET /api/v2/performance/promotions/{promotion_id}/self_claims HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

HTTP/1.1 200 Ok
Content-Type: application/json

{
    "self_claims": [
        {
            "id": 4099,
            "sale_date": "2019-01-29",
            "product_or_activity_ref": "p1",
            "quantity": 150,
            "points_value": 150,
            "user_id": 505,
            "status": "pending",
            "declined_reason": null,
            "created_at": "2019-01-30T14:15:25.000+00:00",
            "updated_at": "2021-01-07T16:41:19.000+00:00",
            "questions_answers": {
                "1174": {
                    "question": "Custom q 1 - free text",
                    "answer": ""
                },
                "1175": {
                    "question": "Custom q 2 - lov r",
                    "answer": ""
                },
                "1176": {
                    "question": "Custom q 3 - lov c",
                    "answer": ""
                },
                "1177": {
                    "question": "Custom q 4 - lov s",
                    "answer": ""
                },
                "1178": {
                    "question": "Custom q 5 - date",
                    "answer": ""
                },
                "1179": {
                    "question": "Custom q 6 - upload",
                    "answer": ""
                }
            }
        },
        {
            "id": 4104,
            "sale_date": "2020-01-02",
            "product_or_activity_ref": "p1",
            "quantity": 10,
            "points_value": 10,
            "user_id": 505,
            "status": "approved",
            "declined_reason": null,
            "created_at": "2020-01-11T14:15:32.000+00:00",
            "updated_at": "2020-01-11T14:15:32.000+00:00",
            "questions_answers": {
                "1174": {
                    "question": "Custom q 1 - free text",
                    "answer": ""
                },
                "1175": {
                    "question": "Custom q 2 - lov r",
                    "answer": ""
                },
                "1176": {
                    "question": "Custom q 3 - lov c",
                    "answer": ""
                },
                "1177": {
                    "question": "Custom q 4 - lov s",
                    "answer": ""
                },
                "1178": {
                    "question": "Custom q 5 - date",
                    "answer": ""
                },
                "1179": {
                    "question": "Custom q 6 - upload",
                    "answer": ""
                }
            }
        },
        {
            "id": 4117,
            "sale_date": "2020-01-23",
            "product_or_activity_ref": "p1",
            "quantity": 5,
            "points_value": 2,
            "user_id": 505,
            "status": "declined",
            "declined_reason": "Not good enough",
            "created_at": "2020-01-23T14:15:32.000+00:00",
            "updated_at": "2020-01-28T10:41:13.000+00:00",
            "questions_answers": {
                "1174": {
                    "question": "Custom q 1 - free text",
                    "answer": ""
                },
                "1175": {
                    "question": "Custom q 2 - lov r",
                    "answer": ""
                },
                "1176": {
                    "question": "Custom q 3 - lov c",
                    "answer": ""
                },
                "1177": {
                    "question": "Custom q 4 - lov s",
                    "answer": ""
                },
                "1178": {
                    "question": "Custom q 5 - date",
                    "answer": ""
                },
                "1179": {
                    "question": "Custom q 6 - upload",
                    "answer": ""
                }
            }
        }
    ]
}

Request Parameters

URL Parameters
Parameter Type Description
status string Status of the claims to be returned. Optional
product_or_activity_ref integer The reference of the product or activity you wish to return claims for. Optional.
user_id integer ID of a user that claims were made by. Optional
created_at_start_date string A parameter for scoping claims that were created from that date onwards. Optional.
created_at_end_date string A parameter for scoping claims that were created on or before the given date. Optional.
date_of_sale_start_date string A parameter for scoping claims with a sale_date from the given date onwards. Optional.
date_of_sale_end_date string A parameter for scoping claims with a sale_date on or before the given date. Optional.
page integer The requested page number. Defaults to page 1 if not supplied. Optional.

Response Attributes

Attribute Type Info
id integer the id of the claim
sale_date string the date of sale as provided on the claim
product_or_activity_ref string the reference of the claimed product or activity
quantity integer the number of items claimed
points_value integer the number of points the claim is worth
user_id integer the id of the user who made the claim
status string the status of the claim - one of: pending, approved, declined
declined_reason string optional - a string indicating the reason for decline if the claim is declined
created_at string the date that the claim was submitted
updated_at string the date that the claim was last updated
questions_answers object an object containing questions identified by their id, along with a child object containing the name of the question, and the answer provided for that question

Update Self Claim

Endpoint to update a pending self claim against a specific self-claim promotion.

HTTP Request

PATCH /api/v2/performance/promotions/{promotion_id}/self_claims/{claim_id}

Header:

PATCH /api/v2/performance/promotions/{promotion_id}/self_claims/{claim_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Body:

{
  "sale_date": "2022-01-29",
  "product_or_activity_ref": "p1",
  "quantity": 150,
  "answers": {
    "1": "Free text answer",
    "2": "2017-06-21",
    "3": "abcdefg",
    "4": "Choice A, Choice B",
    "5": "https://invoicefile/12353.doc"
  }
}

Response:

{
  "id": 1234,
  "user_id": 1,
  "sale_date": "2022-01-29",
  "product_or_activity_ref": "p1",
  "quantity": 150,
  "points": 300,
  "answers": {
    "1": {
        "question": "dynamic question free text?",
        "answer": "Free text answer"
    },
    "2": {
        "question": "dynamic question date select",
        "answer": "2017-06-21"
    },
    "3": {
        "question": "dynamic question scanner",
        "answer": "abcdefg"
    },
    "4": {
        "question": "dynamic question list",
        "answer": "Choice A, Choice B"
    },
    "5": {
        "question": "dynamic question file upload",
        "answer": "https://invoicefile/12353.doc"
    }
  }
}

Request Parameters

Body Parameters
Parameter Type Description
sale_date string The date the product was sold. Mandatory
product_or_activity_ref string The reference of the product or activity you wish to return claims for. Mandatory.
quantity integer The quantity of products sold. Mandatory.
points integer Explicitly set the value of points that the claim is worth. Optional, calculated from the product/activity, quantity and sale date otherwise.
answers string Expected answers depend on their question, which come in the following types: free text, list of values, date select, file upload, scanner. Please provide your answers to dynamic questions as a question_id to answer hash, nested under an answers key. If the question allows multiple answers, add a comma between each answer. Dynamic questions are sometimes mandatory (if the programme administrator has set them to be).

Response Attributes

Attribute Type Info
id integer the id of the claim
user_id string The user ID of the user making the claim.
sale_date string The date the product was sold.
product_or_activity_ref string The reference of the claimed product or activity.
quantity integer The quantity of products sold.
points integer The value of points that the claim is worth.
answers object An object containing questions identified by their id, along with a child object containing the name of the question, and the answer provided for that question.

Decline Self Claim

Endpoint to decline a specified claim.

HTTP Request

POST /api/v2/performance/promotions/{promotion_id}/self_claims/{claim_id}/decline

Header:

POST /api/v2/performance/promotions/{promotion_id}/self_claims/{claim_id}/decline HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
  "reason_for_decline_id": 1,
  "reason_for_decline_text": "Some reason text string"
}

Response:

HTTP/1.1 200 Ok
Content-Type: application/json

{
    "id": 4117,
    "sale_date": "2020-01-23",
    "product_or_activity_ref": "p1",
    "quantity": 5,
    "points_value": 2,
    "user_id": 505,
    "status": "declined",
    "declined_reason": "Not good enough",
    "created_at": "2020-01-23T14:15:32.000+00:00",
    "updated_at": "2020-01-28T10:41:13.000+00:00",
    "questions_answers": {
        "1174": {
            "question": "Custom q 1 - free text",
            "answer": ""
        },
        "1175": {
            "question": "Custom q 2 - lov r",
            "answer": ""
        },
        "1176": {
            "question": "Custom q 3 - lov c",
            "answer": ""
        },
        "1177": {
            "question": "Custom q 4 - lov s",
            "answer": ""
        },
        "1178": {
            "question": "Custom q 5 - date",
            "answer": ""
        },
        "1179": {
            "question": "Custom q 6 - upload",
            "answer": ""
        }
    }
}

Request Parameters

Body Parameters

If decline reasons are active on the promotion, then one of reason_for_decline_id or reason_for_decline_text, but not both, should be provided when declining a claim.

Parameter Type Description
reason_for_decline_id integer Required conditional - The ID of a reason for decline belonging to the promotion.
reason_for_decline_text string Required conditional - A text string of a reason for decline. Can only be provided if the promotion allows free text decline reasons.

Approve Self Claim

Endpoint to approve a specified claim.

HTTP Request

POST /api/v2/performance/promotions/{promotion_id}/self_claims/{claim_id}/approve

Header:

POST /api/v2/performance/promotions/{promotion_id}/self_claims/{claim_id}/approve HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
  "points_value": 100
}

Response:

HTTP/1.1 200 Ok
Content-Type: application/json

{
    "id": 4117,
    "sale_date": "2020-01-23",
    "product_or_activity_ref": "p1",
    "quantity": 5,
    "points_value": 100,
    "user_id": 505,
    "status": "approved",
    "declined_reason": null,
    "created_at": "2020-01-23T14:15:32.000+00:00",
    "updated_at": "2020-01-28T10:41:13.000+00:00",
    "questions_answers": {
        "1174": {
            "question": "Custom q 1 - free text",
            "answer": ""
        },
        "1175": {
            "question": "Custom q 2 - lov r",
            "answer": ""
        },
        "1176": {
            "question": "Custom q 3 - lov c",
            "answer": ""
        },
        "1177": {
            "question": "Custom q 4 - lov s",
            "answer": ""
        },
        "1178": {
            "question": "Custom q 5 - date",
            "answer": ""
        },
        "1179": {
            "question": "Custom q 6 - upload",
            "answer": ""
        }
    }
}

Request Parameters

Body Parameters
Parameter Type Description
points_value integer Optional. If provided, the value of points awarded for the claim will be updated to match the value supplied. If the value exceeds the available programme budget, an error will be returned and the claim will not be approved.

Data Fields

List all Data Fields

A simple endpoint to fetch a list of the data fields for a performance module enabled programme scoped to a Promotion. Returns an array of data fields as a flat list.

GET /api/v2/performance/promotions/{promotion_id}/data_fields HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
HTTP/1.1 200 OK
Content-Type: application/json

[
    {
        "id": 196,
        "promotion_id": 1,
        "name": "size",
        "label": "Size",
        "mandatory": true,
        "field_type": "list_values",
        "answers": "Small\r\nMedium\r\nLarge",
        "created_at": "2016-04-14T13:34:03.000+01:00",
        "updated_at": "2016-04-14T13:34:03.000+01:00",
        "position": 1
    },
    {
        "id": 197,
        "promotion_id": 1,
        "name": "serial_number",
        "label": "Serial Number",
        "mandatory": true,
        "field_type": "free_text",
        "answers": null,
        "created_at": "2016-04-14T13:35:03.000+01:00",
        "updated_at": "2016-04-14T13:35:03.000+01:00",
        "position": 2
    }
]

HTTP Request

GET /api/v2/performance/promotions/{promotion_id}/data_fields HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [
    {
      "customer_name": "John",
      "invoice_date": "2018-01-01",
      "product_or_activity_ref": "PRE",
      "quantity": 2,
      "value_of_sale": 100.35,
      "username": "john.doe@email.null"
    }
  ]
}

Attributes

Attribute Type Info
id integer data_field id
promotion_id integer promotion id
name string data_field name in snake case format.
label string data_field label.
mandatory boolean Whether this field is required
field_type string One of: 'free_text', 'numeric', 'list_values', 'date'
answers string A '\r\n' separated list of allowed answers
created_at date The time at which this field was created
updated_at date The time at which this field was last updated
position integer Position of the data field within the form

Performance Categories

List Performance Categories

Endpoint to fetch a list of the performance categories for a performance module enabled programme

GET /api/v2/performance/performance_categories HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
HTTP/1.1 200 OK
Content-Type: application/json
[
    {
        "id": 1,
        "name": "Category Name 1"
    },
    {
        "id": 2,
        "name": "Category Name 2"
    }
]

HTTP Request

GET /api/v2/performance/performance_categories

Parameters

Parameter Type Info
id integer The id of the performance category
name string The name of the performance category

Performance Products

Creating a Product

Endpoint to create performance products for a programme with the performance module enabled.

POST /api/v2/performance/performance_product_batches HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "performance_products":[
        {
            "performance_category_id": 1,
            "name": "Test Product 1",
            "ref": "abc1236",
            "product_type": "product",
            "value": 10,
            "description": "some description"
        },
        {
            "performance_category_id": 1,
            "name": "Test Product 2",
            "ref": "abc5766",
            "product_type": "product",
            "value": 10,
            "description": "some description"
        }
    ]
}
HTTP/1.1 201 Created
Content-Type: application/json

[
    {
        "id": 1,
        "peformance_category_id": 1,
        "name": "Test Product 1",
        "ref": "abc1236",
        "product_type": "product",
        "value": 10,
        "description": "some description"
    },
    {
        "id": 2,
        "peformance_category_id": 1,
        "name": "Test Product 2",
        "ref": "abc5766",
        "product_type": "product",
        "value": 10,
        "description": "some description"
    }
]

HTTP Request

POST /api/v2/performance/performance_product_batches

Attributes

Attribute Type Info
performance_category_id integer The id of the category the product will belong to. This must be valid for your programme
name string The name of the product. Must be unique
ref string The reference for the product. Must be unique
product_type string Must be either 'product' or 'activity'
value integer A positive two digit number. Must be the value in RRP or the cost value of the product in your programme's currency. If the product_type is 'product', this must be provided
description text Some text describing the product. Optional

Updating a Product

Endpoint to update performance products for a programme with the performance module enabled.

PUT /api/v2/performance/performance_product_batches HTTP/1.1
PATCH /api/v2/performance/performance_product_batches HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "performance_products":[
        {
            "id": 1,
            "performance_category_id": 1,
            "name": "Update Name",
            "ref": "abc1236",
            "product_type": "product",
            "value": 10,
            "description": "Updated Description"
        }
    ]
}
HTTP/1.1 200 OK
Content-Type: application/json

[
    {
        "id": 1,
        "peformance_category_id": 1,
        "name": "Updated name",
        "ref": "abc1236",
        "product_type": "product",
        "value": 10,
        "description": "Updated description"
    }
]

HTTP Request

PUT /api/v2/performance/performance_product_batches
PATCH /api/v2/performance/performance_product_batches

Attributes

Attribute Type Info
id integer The id of the performance product to be updated
performance_category_id integer The id of the category the product will belong to. This must be valid for your programme
name string The name of the product. Must be unique
ref string The reference for the product. Must be unique
product_type string Must be either 'product' or 'activity'
value integer A positive two digit number. Must be the value in RRP or the cost value of the product in your programme's currency. If the product_type is 'product', this must be provided
description text Some text describing the product. Optional

Reward Points

Get Reward Points

This endpoint returns reward points for a specified promotion. Results are paginated at 100 reward points per page.

Request:

GET /api/v2/performance/promotions/{promotion_id}/reward_points?page=1 HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

HTTP/1.1 200 OK
Content-Type: application/json

[
    {
        "id": 166,
        "promotion_id": 4,
        "name": "product 1",
        "type": "product",
        "reference": "p1",
        "active": true,
        "quantity": 1,
        "points_per_quantity": 1,
        "sale_date_from": "2013-02-01",
        "sale_date_to": "2022-12-31",
        "user_groups": [
            350,
            355
        ],
        "created_at": "2017-06-27T10:58:31.000+01:00",
        "updated_at": "2017-06-27T10:58:31.000+01:00"
    },
    {
        "id": 6345,
        "promotion_id": 4,
        "name": "product 2",
        "type": "product",
        "reference": "p2",
        "active": true,
        "quantity": 1,
        "points_per_quantity": 1,
        "sale_date_from": "2016-12-18",
        "sale_date_to": "2026-11-19",
        "user_groups": [],
        "created_at": "2021-07-25T15:12:58.000+01:00",
        "updated_at": "2021-07-25T15:12:58.000+01:00"
    },
    {
        "id": 6346,
        "promotion_id": 4,
        "name": "product 3",
        "type": "product",
        "reference": "p3",
        "active": true,
        "quantity": 1,
        "points_per_quantity": 1,
        "sale_date_from": "2016-12-18",
        "sale_date_to": "2026-11-19",
        "user_groups": [],
        "created_at": "2021-07-25T15:13:37.000+01:00",
        "updated_at": "2021-07-25T15:13:37.000+01:00"
    }
]

HTTP Request

GET /api/v2/performance/promotions/{promotion_id}/reward_points?page=1

URL Parameters

Attribute Type Info
promotion_id integer Required. The ID of the promotion to return reward points for.

Query Parameters

Attribute Type Info
page integer Optional. The requested page number. Defaults to page 1 if not supplied.

Create Reward Points

This endpoint creates a reward point for a specified promotion.

Request:

POST /api/v2/performance/promotions/{promotion_id}/reward_points HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "reference": "p1",
    "user_group_ids": [355, 350],
    "quantity": 2,
    "points_per_quantity": 5,
    "date_from": "2012-02-28",
    "date_to": "2025-01-31",
    "active": true
}

Response:

HTTP/1.1 201 CREATED
Content-Type: application/json

{
    "id": 166,
    "promotion_id": 4,
    "name": "product 1",
    "type": "product",
    "reference": "p1",
    "active": true,
    "quantity": 2,
    "points_per_quantity": 5,
    "sale_date_from": "2012-02-28",
    "sale_date_to": "2025-01-31",
    "user_groups": [
        350,
        355
    ],
    "created_at": "2017-06-27T10:58:31.000+01:00",
    "updated_at": "2017-06-27T10:58:31.000+01:00"
}

HTTP Request

POST /api/v2/performance/promotions/{promotion_id}/reward_points

URL Parameters

Attribute Type Info
promotion_id integer Required. The ID of the promotion the reward point belongs to.

Body Parameters

Parameter Type Description
reference string Required. Ref of the performance product that the reward point is to be claimed against.
user_group_ids array Optional. An array of all of the user groups that should be eligible for the reward point.
quantity integer Required. The quantity that must be claimed to qualify for the reward point. This must be 1 if returns are enabled on your promotion.
points_per_quantity integer Required. The number of points to award per quantity.
date_from date Required. The date the reward point is eligible from.
date_to date Required. The date the reward point is eligible to.
active boolean Optional. The active status of the reward point. Defaults to false (not active).

Update Reward Points

This endpoint updates a single reward point for a specified promotion.

Request:

PATCH /api/v2/performance/promotions/{promotion_id}/reward_points/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "user_group_ids": [355, 350],
    "quantity": 2,
    "points_per_quantity": 5,
    "date_from": "2012-02-28",
    "date_to": "2025-01-31",
    "active": true
}

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": 166,
    "promotion_id": 4,
    "name": "product 1",
    "type": "product",
    "reference": "p1",
    "active": true,
    "quantity": 1,
    "points_per_quantity": 1,
    "sale_date_from": "2013-02-01",
    "sale_date_to": "2022-12-31",
    "user_groups": [
        350,
        355
    ],
    "created_at": "2017-06-27T10:58:31.000+01:00",
    "updated_at": "2017-06-27T10:58:31.000+01:00"
}

HTTP Request

PATCH /api/v2/performance/promotions/{promotion_id}/reward_points/{id}

URL Parameters

Attribute Type Info
promotion_id integer Required. The ID of the promotion the reward point belongs to.
id integer Required. The ID of the reward point to update.

Body Parameters

Parameter Type Description
user_group_ids array An array of all of the user groups that should be eligible for the reward point.
quantity integer The quantity that must be claimed to qualify for the reward point. This must be 1 if returns are enabled on your promotion.
points_per_quantity integer The number of points to award per quantity.
date_from date The date the reward point is eligible from.
date_to date The date the reward point is eligible to.
active boolean The active status of the reward point.

Sales Data

Create Sales Data

Endpoint to create claims against specific promotion. Claims are created by using the data_field names from above as key/value pairs.

Request:

POST /api/v2/performance/data HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "data": [
        {
            "sale_date": "2022-03-10",
            "product_or_activity_ref": "TEST-217744",
            "quantity": 1,
            "user_id": 170944
        },
        {
            "sale_date": "2022-03-10",
            "product_or_activity_ref": "TEST-217744",
            "quantity": 1,
            "user_id": 170944
        }
    ]
}

Success response:

HTTP/1.1 201 CREATED
Content-Type: Application/json

{
    "results": [
        {
            "claims": [
                {
                    "claim": {
                        "id": 48992,
                        "state": "approved",
                        "points": 1
                    },
                    "errors": []
                }
            ]
        },
        {
            "claims": [
                {
                    "claim": {
                        "id": 48993,
                        "state": "approved",
                        "points": 1
                    },
                    "errors": []
                },
                {
                    "claim": {
                        "id": 48994,
                        "state": "approved",
                        "points": 1
                    },
                    "errors": []
                }
            ]
        },
        {
            "claims": [
                {
                    "claim": {
                        "id": null,
                        "state": null,
                        "points": null
                    },
                    "errors": [
                        "No reward points found"
                    ]
                }
            ]
        },
        {
            "claims": [
                {
                    "claim": {
                        "id": null,
                        "state": null,
                        "points": null
                    },
                    "errors": [
                        "No reward points found",
                        "Product not found"
                    ]
                }
            ]
        },
        {
            "claims": [
                {
                    "claim": {
                        "id": 48995,
                        "state": "approved",
                        "points": 1
                    },
                    "errors": []
                }
            ]
        },
        {
            "claims": [
                {
                    "claim": {
                        "id": null,
                        "state": null,
                        "points": null
                    },
                    "errors": [
                        "No reward points found",
                        "User not found"
                    ]
                }
            ]
        }
    ]
}

Error response:

HTTP/1.1 422 UNPROCESSABLE ENTITY
Content-Type: Application/json

{
    "errors": [
        "A free text question: Please complete this field"
    ],
    "index_of_failed_data": 5
}

HTTP Request

POST /api/v2/performance/promotions/{promotion_id}/data

Attributes

Attribute Type Info
sale_date date The date when this piece of data was created
product_or_activity_ref string The SKU for the performance product to claim against
returns_identifier string The returns_identifier to be assigned to the given claim. ( Only required if returns are enabled on the given promotion. Uniqueness for the combination of this field, product ref and the user is required. )
quantity integer The quantity of products sold. See note on quantity below.
username string The username or email for the user to assign points to ( Either this or the user_id field needs to be supplied. )
user_id user_id The MyRewards user ID for the user to assign points to ( Either this or the username field needs to be supplied. )

You will also need to provide any custom data fields as extra keys for each piece of claim data in snake case format which is provided in the name field for the GET List Data Fields for a Promotion. The Promotion ID will need to correspond to an existing & valid promotion

If one record in a set being uploaded fails to be created either by being invalid (see note on validity below) or through a programme not having enough points - all records in the request will fail to be created and you will receive a 422 unprocessable entity response along with error details and the zero based index of the record that caused the failure.

Validity - A record is considered invalid if there is something wrong with the claim that would be created as a result. For example if a required answer has not been provided. A record will not be considered invalid if we cannot find the user, we cannot find the product, or we cannot find an appropriate reward to assign as without these key pieces of information we can't attempt to create a claim, instead we will continue with the remainder of the request and create the claims that we can. This is done so that if you are sending multiple requests and one of them fails because of a problem with the user or product/reward which is highly likely to happen with batches, we do not fail the entire batch for this one reason. You will still receive a 201 created response if not all of the records resulted in a valid claim, but you will receive a response object detailing what claims if any were created for each record, and what errors prevented a claim from being created where appropriate. This means that even if no claims are created, you will still receive a 201 created response, and you must use the response data to determine if any claims were created.

Quantity - With data upload promotions, if your reward point requires a quantity of 2 or more to be sold before earning points, then we accumulate sales until the necessary quantity is reached. Therefore, if you have a minimum quantity of 2 and you send data for 1, we will still create a claim for 1 unit, but it will be assigned 0 points. If you then send another request for 1 unit, thus bringing your total quantity sold to 2, then we will create a claim with the appropriate points.

Returned Claims

Create Returned Claims

Endpoint to create returned claims against specific claim. Returned claims are created by specifiying identifiers (key/value pairs) for a specific claim.

Request:

POST /api/v3/performance/promotions/{promotion_id}/returned_claims HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "returns_data": [
        {
            "user_id": 170944,
            "returns_identifier": "identifier_001",
            "product_or_activity_ref": "TEST-217744",
            "quantity": 5
        },
        {
            "username": "john.doe",
            "returns_identifier": "identifier_002",
            "product_or_activity_ref": "TEST-115647",
            "quantity": 2
        }
    ]
}

Success response:

HTTP/1.1 201 CREATED
Content-Type: Application/json

Error response(s):

HTTP/1.1 400 BAD REQUEST
Content-Type: Application/json

{
    "errors": [
        "please supply valid product_or_activity_ref value(s), for 1st entry",
        "please supply valid returns_identifier, product_or_activity_ref, quantity, user_id value(s), for 2nd entry"
    ]
}
HTTP/1.1 400 BAD REQUEST
Content-Type: Application/json

{
    "errors": [
        "Number of return entries provided is above the max allowed of 50"
    ]
}
HTTP/1.1 400 BAD REQUEST
Content-Type: Application/json

{
    "errors": [
      "No returns data was provided"
    ]
}
HTTP/1.1 400 BAD REQUEST
Content-Type: Application/json

{
    "errors": [
      "Returns are not enabled on this promotion"
    ]
}
HTTP/1.1 404 Not Found
Content-Type: Application/json

{
    "errors": [
      "Promotion not found"
    ]
}

HTTP Request

POST /api/v2/performance/promotions/{promotion_id}/returned_claims

Attributes

Attribute Type Info
product_or_activity_ref string The SKU for the performance product the original claim was assigned.
quantity integer The quantity to return against the claim.
returns_identifier string The returns_identifier that is assigned to the given claim.
username string The username or email for the user the original claim was created against, this will be the user points are deducted from. ( Either this or the user_id field needs to be supplied. )
user_id integer The MyRewards user ID for the user the original claim was created against, this will be the user points are deducted from. ( Either this or the username field needs to be supplied. )

If one record in a set being uploaded fails to be created then all requested records will not be created and an error object will be given back. This object will contain the errors that need to be addressed before proceededing again with the request.

Recognition Module

Recognition Wall

Get Recognition Wall

This endpoint returns wall posts from the recognition wall on your programme (if activated). Results are paginated at 100 wall posts per page and can be filtered down by the specified query parameters. Results will be returned from newest to oldest.

Request:

GET /api/v2/recognition/recognition_wall HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
  "campaign_ids" : "1,2,3",
  "award_id" : 123,
  "receiver_id": 508,
  "sender_id": 510,
  "created_at_date": 2022-01-31,
  "created_at_end_date": 2022-02-28,
  "page": 1,
  "locale": "fr"
}

Response:

HTTP/1.1 200 OK
Content-Type: application/json

[
    {
        "id": 11914,
        "award_id": 4723,
        "campaign_id": 194,
        "sender_id": 508,
        "receiver_id": 508,
        "user_group_id": 351,
        "image": null,
        "content": "<p>John<br />\r\nDoe<br />\r\njohn.doe@email.null<br />\r\n27/04/2022<br />\r\n<br />\r\n0<br />\r\n27/04/2022<br />\r\n-<br />\r\n-<br />\r\n-<br />\r\n-<br />\r\n-<br />\r\n-<br />\r\n<a href='https://yourdomainname.com/liquid/recognition/4723/view_submission' target='_blank'>View Submission</a><br />\r\n<a href='https:/yourdomainname.com/pdf/awards/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6NDcyMywic3ViIjoiQXdhcmQifQ.uMTNhhnGCOJMwNDuOXDyFqdxKJvrf2B0jogdWYZfFQg/export_pdf.pdf' target='_blank'>Click here</a><br />\r\n</p>\r\n",
        "created_at": "2022-04-27T10:02:59.000+01:00",
        "updated_at": "2022-04-27T10:02:59.000+01:00",
        "likes": 3,
        "comments": []
    },
    {
        "id": 11913,
        "award_id": 4722,
        "campaign_id": 136,
        "sender_id": 511,
        "receiver_id": 508,
        "user_group_id": 351,
        "image": "https://yourdomainname.com/s3/W1siZiIsIjIwMjIvMDQvMjcvMDgvNTQvNDkvYzNmMDNlMGItYzU1Ni00YmMxLWI4MzgtODQwYWZmODljOWIyL3N0b2NrLXZlY3Rvci12ZWN0b3ItZGFyay1ibHVlLXNlYW1sZXNzLXBhdHRlcm4td2l0aC1nb2xkLWZvaWwtY29uc3RlbGxhdGlvbnMtc3RhcnMtYW5kLWNsb3Vkcy13YXRlcmNvbG9yLW5pZ2h0LTEzMzE1Njc3OTIuanBnIl1d?sha=809982617de31702",
        "content": "<p>Thanks</p>\r\n",
        "created_at": "2022-04-27T09:58:42.000+01:00",
        "updated_at": "2022-04-27T09:58:42.000+01:00",
        "likes": 0,
        "comments": [
            {
                "user_id": 511,
                "comment": "Smashing work"
            },
            {
                "user_id": 505,
                "comment": "Wow, nice"
            }
        ]
    }
]

HTTP Request

GET /api/v2/recognition/recognition_wall

Query Parameters

Attribute Type Info
campaign_ids string Optional. ID or ID's of programme campaigns to restrict wall post activity to.
award_id integer Optional. ID of the award the wall post activity relates to.
receiver_id integer Optional. ID of the user the wall post activity relates to.
sender_id integer Optional. ID of the sender the wall post activity relates to.
created_at_date date Optional. A parameter for scoping content that was created from that date onwards. Must be provided in ISO 8601 date format YYYY-MM-DD.
created_at_end_date date Optional. A parameter for scoping content that was created on or before the given date. Must be provided in ISO 8601 date format YYYY-MM-DD.
page integer Optional. The requested page number. Defaults to page 1 if not supplied.
locale string Optional. Will return the wall post content in the locale provided. If no locale is provided, the default programme locale will be used

Nominations

Update a Nomination's status

An endpoint to update a status of a nomination for a given campaign, by passing a status parameter. A valid approver for the nomination must also be provided. You will be returned the updated JSON for the given nomination.

PATCH /api/v2/campaigns/{campaign_id}/nominations/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
  "transition" : "approve",
  "approver" : 123
}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id" : "1",
  "state" : "approved_l1",
}
PATCH /api/v2/campaigns/{campaign_id}/nominations/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
  "transition" : "decline",
  "approver" : 123,
  "declined_reason" : "Already nominated"
}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id" : "1",
  "state" : "declined_l1",
  "declined_reason" : "Already nominated"
}

HTTP Request

PATCH /api/v2/campaigns/{campaign_id}/nominations/{id}

URL Parameters

Attribute Type Info
id integer (required) campaign_award_request id
campaign_id integer (required) campaign id

Body Parameters

Attribute Type Info
approver integer (required) the approver's user id
reason string (optional) string which can be provided when declining a nomination
transition string (required) a valid transition to be performed on the award (approve or decline only)

Approver Information

The approver should be a valid approver for the nomination, and for the approver level.

Reason Information

When declining a nomination an optional string can be provided. This is saved to the nomination when it is declined.

State Transition Information

Nominations can only transition to a state allowed by its current state. For example an award with state 'pending_l1' can transition to 'approved_l1' but not to 'approved_l2'. Only "approve" or "decline" can be provided to the API.

Submissions

Get all submissions

An endpoint to get all submissions for a given campaign. Results are paginated and return 100 records per page.

HTTP Request

GET /api/v2/campaigns/{campaign_id}/submissions

Query Parameters

Parameter Type Description
page integer The page number that you wish to view. Optional
status string Status of the submissions to be returned. Optional
user_id integer ID of a sender that submissions were made by. Optional
created_at_date date A parameter in ISO-8601 format for scoping submissions that were created from that date onwards. Optional.
created_at_end_date date A parameter in ISO-8601 format for scoping submissions that were created on or before the given date. Optional.

Request:

GET /api/v2/campaigns/{campaign_id}/submissions HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

HTTP/1.1 200 OK
Content-Type: Application/json

[
    {
        "id": 157,
        "award_id": 1317,
        "status": "approved_l1",
        "sender_id": 111744,
        "points_requested": 100,
        "created_at": "2019-01-30T14:15:25.000+00:00",
        "updated_at": "2021-01-07T16:41:19.000+00:00",
        "questions_answers": {
            "1174": {
                "question": "Custom q 1 - free text",
                "answer": ""
            },
            "1175": {
                "question": "Custom q 2 - lov r",
                "answer": ""
            },
            "1176": {
                "question": "Custom q 3 - lov c",
                "answer": ""
            }
        },
        "points_approved": 100,
        "approved_by": {
            "level_1": {
                "user_id": 505,
            },
            "level_2": {
                "user_id": null,
            }
        },
        "declined_by": {
            "level_1": {
                "user_id": null,
                "reason": null
            },
            "level_2": {
                "user_id": null,
                "reason": null
            }
        }
    },
    {
        "id": 157,
        "award_id": 1318,
        "status": "pending_l1",
        "sender_id": 111744,
        "points_requested": 200,
        "created_at": "2019-01-30T14:15:25.000+00:00",
        "updated_at": "2021-01-07T16:41:19.000+00:00",
        "questions_answers": {
            "1174": {
                "question": "Custom q 1 - free text",
                "answer": ""
            },
            "1175": {
                "question": "Custom q 2 - lov r",
                "answer": ""
            },
            "1176": {
                "question": "Custom q 3 - lov c",
                "answer": ""
            },
        },
        "points_approved": 0,
        "approved_by": {
            "level_1": {
                "user_id": null,
            },
            "level_2": {
                "user_id": null,
            }
        },
        "declined_by": {
            "level_1": {
                "user_id": null,
                "reason": null
            },
            "level_2": {
                "user_id": null,
                "reason": null
            }
        }
    }
]

Update a Submission

An endpoint to update a submission for a given recognition campaign.

HTTP Request

POST /api/v2/campaigns/{campaign_id}/submissions/{submission_id}/approve

Request Parameters

Body Parameters

Parameter Type Description
submission_id integer The ID of the submission you want to approve
campaign_id integer The ID of the campaign that the submission belongs to

Request:

POST /api/v2/campaigns/{campaign_id}/submissions/{submission_id}/approve HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

HTTP/1.1 200 OK
Content-Type: Application/json

[
    {
        "id": 157,
        "award_id": 1940,
        "status": "approved_l1",
        "sender_id": 119742,
        "points_requested": 0,
        "created_at": "2019-02-21T11:45:35.000+00:00",
        "updated_at": "2019-02-21T11:45:35.000+00:00",
        "questions_answers": {
            "355": {
                "question": "Please enter your unique reference number:",
                "answer": "ref-001"
            }
        },
        "points_approved": 0,
        "approved_by": {
            "level_1": {
                "user_id": null
            },
            "level_2": {
                "user_id": null
            }
        },
        "declined_by": {
            "level_1": {
                "user_id": null,
                "reason": null
            },
            "level_2": {
                "user_id": null,
                "reason": null
            }
        }
    }
]

Decline Submission

Endpoint to decline a given submission.

POST /api/v2/campaigns/{campaign_id}/submissions/{id}/decline HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
  "reason_for_decline_id": "An id for a decline reason",
  "reason_for_decline_text": "Some reason text string"
}
HTTP/1.1 200 Ok
Content-Type: application/json

{
    "id": 162668,
    "award_id": 2078,
    "status": "declined_l2",
    "sender_id": 119742,
    "points_requested": 0,
    "created_at": "2021-09-22T15:52:18.000+01:00",
    "updated_at": "2021-09-22T15:52:18.000+01:00",
    "questions_answers": {
        "355": {
            "question": "Custom q 1 - free text",
            "answer": ""
        }
    },
    "points_approved": 0,
    "approved_by": {
        "level_1": {
            "user_id": null
        },
        "level_2": {
            "user_id": null
        }
    },
    "declined_by": {
        "level_1": {
            "user_id": null,
            "reason": null
        },
        "level_2": {
            "user_id": null,
            "reason": "Declined Reason"
        }
    }
}

HTTP Request

POST /api/v2/campaigns/{campaign_id}/submissions/{id}/decline

Request Parameters

Body Parameters

If decline reasons are active on the campaign, then one of reason_for_decline_id or reason_for_decline_text, but not both, should be provided when declining a submission.

Parameter Type Description
reason_for_decline_id integer The ID of a reason belonging to the campaign. Mandatory if decline reasons enabled on programme.
reason_for_decline_text string A text string for a decline reason, can only be provided if the campaign allows free text decline reasons. Optional.

Reward Module

Instant Point Vouchers (IPV)

Create an IPV

Header:

POST /api/v2/reward/codes HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Body:

{
    "value": 1000,
    "description": "Competition winner.",
    "expiry_date": "2025-12-31",
    "send_email": "john.doe@email.null"
}

Response:

{
    "id" : 1,
    "value" : 1000,
    "description" : "Competition winner.",
    "expiry_date" : "2025-12-31",
    "send_email" : "john.doe@email.null",
    "code_value" : "XXXX-YYYY-ZZZZ",
    "batch_reference" : "SSSS",
    "state" : "active",
    "issued": true,
    "programme_id" : 123,
    "user_id" : 25
}

Generate Reward IPV codes for Programmes with the Rewards Module.

HTTP Request

POST /api/v2/reward/codes

Attributes

Attribute Type Info
value integer Required, must be a positive integer. Points value of the IPV
description string Optional, text field
expiry_date date Required, must be in the future and in the format YYYY-MM-DD
send_email string Optional, valid email address to which the code will be sent. If provided, the 'Send a code' email messages must be configured. Response will have issued set to true

Get an IPV

Header:

GET /api/v2/reward/codes/{id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Response:

{
    "id" : 1,
    "value" : 1000,
    "description" : "Competition winner.",
    "expiry_date" : "2025-12-31",
    "send_email" : "john.doe@email.null",
    "code_value" : "XXXX-YYYY-ZZZZ",
    "batch_reference" : "SSSS",
    "state" : "active",
    "issued": true,
    "programme_id" : 123,
    "user_id" : 25
}

To view the details of an IPV code.

HTTP Request

GET /api/v2/reward/codes/{id}

Points Overrides

Update a points override

Set or update a points override for a product within your programme.

If MyRewards has already imported the product from GPS, the points override will take effect on your programme immediately. Otherwise, you will need to wait for the daily sync to have run before the override takes effect.

HTTP Request

PUT /api/v2/points_overrides/{gps_product_id}

Header:

PUT /api/v2/points_overrides/{gps_product_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

Body:

{
    "points": 200
}

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "programme_id": 123,
    "gps_product_id": 5678,
    "points": 200
}

Request Parameters

URL Parameters
Parameter Type Description
gps_product_id integer The product ID (from GPS) whose points you want to override
Body Parameters
Parameter Type Description
points integer The points override you want to set. Must be >= 0

Delete a points override

Remove a points override for a product within your programme.

HTTP Request

DELETE /api/v2/points_overrides/{gps_product_id}

Header:

DELETE /api/v2/points_overrides/{gps_product_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}

Response (override found for product id):

HTTP/1.1 204 No Content

Response (no override found for product id):

HTTP/1.1 404 Not Found
Content-Type: application/json

{
    "errors": ["No override found for product id"]
}

Request Parameters

URL Parameters
Parameter Type Description
gps_product_id integer The product ID (from GPS) whose points you want to override

SSO (Single Sign On)

SAML

Our SSO can use SAML 2.0 to facilitate IdP-initiated Single Sign On to a MyRewards Programme

In this case MyRewards acts as a Service Provider (SP) for a given programme

The client platform is acting as an Identity Provider (IdP)

Process flow

  1. User is challenged to authenticate at the IdP side
  2. User Logs in to the IdP
  3. User selects access to SP
  4. IdP Responds with assertion to user
  5. User's browser POSTs this assertion to the MyRewards programme
  6. Session established on MyRewards and user is granted access

The Assertion

Example SAML assertion:

<samlp:Response ID="_UNIQUE-ID" Version="2.0" IssueInstant="2020-01-01T00:00:00.000000Z" Destination="https://programme-name.com/saml/consume" xmlns="urn:oasis:names:tc:SAML:2.0:protocol">
 <!-- [1] -->
 <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
  https://www.client-company.com
 </saml:Issuer>

 <!-- [2] -->
 <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>
   <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xmlexc-c14n#" />
   <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsasha1" />
   <ds:Reference URI="#_UNIQUE-ID">
    <ds:Transforms>
     <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-excc14n#" />
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
    <ds:DigestValue>...digestValue...</ds:DigestValue>
   </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>...signatureValue...</ds:SignatureValue>
  <ds:KeyInfo>
   <ds:X509Data>
    <ds:X509Certificate>...Certificate...</ds:X509Certificate>
   </ds:X509Data>
  </ds:KeyInfo>
 </ds:Signature>

 <samlp:Status>
  <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
 </samlp:Status>

 <saml:Assertion Version="2.0" ID="_UNIQUE-ID" IssueInstant="2020-01-01T00:00:00.000000Z" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
  <!-- [1] -->
  <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">
   https://www.client-company.com
  </saml:Issuer>

  <!-- [3] -->
  <saml:Subject>
   <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">Principal ID</saml:NameID>
  </saml:Subject>

  <!-- [4] -->
  <saml:Conditions NotBefore="2020-01-01T00:00:00.000000Z" NotOnOrAfter="2020-01-01T02:00:00.000000Z">
   <saml:AudienceRestriction>
    <saml:Audience>https://programme-name.com/saml/metadata</saml:Audience>
   </saml:AudienceRestriction>
  </saml:Conditions>

  <saml:AuthnStatement AuthnInstant="2020-01-01T00:00:00.000000Z">
   <saml:AuthnContext>
    <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
   </saml:AuthnContext>
  </saml:AuthnStatement>

  <saml:AttributeStatement>
   <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
    <saml:AttributeValue xmlns:q1="http://www.w3.org/2001/XMLSchema" p6:type="q1:string" xmlns:p6="http://www.w3.org/2001/XMLSchema-instance">
     john.doe@email.null
    </saml:AttributeValue>
   </saml:Attribute>
  </saml:AttributeStatement>
 </saml:Assertion>
</samlp:Response>

Example form:

<form method="post" action="https://programme-name.com/saml/consume">
 <input type="hidden" name="SAMLResponse" value="AbCdefgh..." />
 <input type="submit" value="Submit" />
</form>

Example conditions:

<saml:Conditions NotBefore="2020-01-01T00:00:00.000000Z" NotOnOrAfter="2020-01-01T02:00:00.000000Z">
 ...
</saml:Conditions>

The value of the SAMLResponse parameter is a Base64-encoded <samlp:Response> element, which is transmitted to the service provider via the browser (see "Example form" for an example).

The assertion must have the following sub-elements (shown with namespaces from "Example SAML assertion"):

saml:Issuer [1]

Name of the IdP in the form of a url e.g. https://client-company.com.

ds:Signature [2]

All SAML 2.0 Assertions are signed by default. The client company (identity provider) will be required to include the X.509 Certificate public key in the assertion itself. MyRewards (service provider) will use this to verify the signature.

saml:Subject [3]

The subject <saml:NameID> is always the unique identifier of the user - by default this set as transient, we require this to be persistent - this is as understood by the IdP.

saml:Conditions [4]

This is the timeframe within which the assertion is valid - our preference is to be set to allow for 2 minutes either side to account for clock drift between servers. MyRewards will verify the validity of an assertion with respect to these conditions after validating the signature.

Our servers are synchronised daily to Europe/London timezone - this will change with Daylight Saving Time. We expect the IdP has their server clocks similarly synchronised. The timestamp used will be in Coordinated Universal Time (UTC) and we strongly recommend adding a window of 1 hour plus 2 minutes to account for both clock drift and Daylight Saving Time.

For example, if the date/time was Tuesday 9th October, 2018 15:09 (BST) then we would expect to see the <saml:Conditions> element look like the snippet shown in "Example conditions".

saml:AttributeStatement

The attribute statement is a list of name/value pairs conveying information about the user themselves. We only use one <saml:Attribute> with a Name specified by the programme configuration (uid by default) and expect the value to be one of:

The value we expect, as well as the name of the attribute to check, is determined by the programme configuration.

Next steps

The following information is required to set up SAML SSO on the MyRewards system:

In response, you will be provided with a metadata file - this can often be useful for automatically configuring some IdP systems such as Active Directory Federated Services.

Further information

For further information on SAML 2.0 please go to the official SAML 2.0 websites:

SAML User Provisioning

If your programme has been configured to allow user provisioning for SAML SSO you may pass additional attributes in your SAMLResponse to be used to create a user if they don't exist (unless your programme is configured with id as the user identifier, in which case we will never attempt to create a user and you must manage user creation in some other way) or update a user if they do exist. If your programme has not been set up to allow user provisioning, any additional attributes sent will be ignored.

User identifier Create user Update user
id No Yes
email Yes Yes
username Yes Yes

The SAML AttributeStatement

Example SAML assertion with additional attributes:

<samlp:Response ID="_UNIQUE-ID" Version="2.0" IssueInstant="2020-01-01T00:00:00.000000Z" Destination="https://programme-name.com/saml/consume" xmlns="urn:oasis:names:tc:SAML:2.0:protocol">
 <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
  https://www.client-company.com
 </saml:Issuer>
 <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>
   <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xmlexc-c14n#" />
   <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsasha1" />
   <ds:Reference URI="#_UNIQUE-ID">
    <ds:Transforms>
     <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-excc14n#" />
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
    <ds:DigestValue>...digestValue...</ds:DigestValue>
   </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>...signatureValue...</ds:SignatureValue>
  <ds:KeyInfo>
   <ds:X509Data>
    <ds:X509Certificate>...Certificate...</ds:X509Certificate>
   </ds:X509Data>
  </ds:KeyInfo>
 </ds:Signature>

 <samlp:Status>
  <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
 </samlp:Status>

 <saml:Assertion Version="2.0" ID="_UNIQUE-ID" IssueInstant="2020-01-01T00:00:00.000000Z" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">
   https://www.client-company.com
  </saml:Issuer>
  <saml:Subject>
   <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">Principal ID</saml:NameID>
  </saml:Subject>
  <saml:Conditions NotBefore="2020-01-01T00:00:00.000000Z" NotOnOrAfter="2020-01-01T02:00:00.000000Z">
   <saml:AudienceRestriction>
    <saml:Audience>https://programme-name.com/saml/metadata</saml:Audience>
   </saml:AudienceRestriction>
  </saml:Conditions>

  <saml:AuthnStatement AuthnInstant="2020-01-01T00:00:00.000000Z">
   <saml:AuthnContext>
    <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
   </saml:AuthnContext>
  </saml:AuthnStatement>

  <saml:AttributeStatement>
    <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">john.doe@email.null</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="username" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">john.doe</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">john.doe@email.null</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="firstname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">John</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="lastname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">Doe</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="communication_preference" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">sms</saml:AttributeValue>
      <saml:AttributeValue xsi:type="xs:string">email</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="registration_question_2" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">Working From Home</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="registration_question_16" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">Monday</saml:AttributeValue>
      <saml:AttributeValue xsi:type="xs:string">Wednesday</saml:AttributeValue>
      <saml:AttributeValue xsi:type="xs:string">Friday</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="chosen_locale" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">en</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="user_group_id" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">10</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="company" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">Org Inc</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="company_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">Org Inc</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="company_identifier" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
      <saml:AttributeValue xsi:type="xs:string">org-inc-01</saml:AttributeValue>
    </saml:Attribute>
  </saml:AttributeStatement>
 </saml:Assertion>
</samlp:Response>

Exactly which attributes we will accept depend upon the configuration of your user fields, however you must still always have a <saml:Attribute> with a Name specified by the programme configuration (uid by default) and expect the value to be one of:

The following standard user fields may be provided as an attributes Name value e.g. <saml:Attribute Name="firstname">:

Companies

If your programme uses a free text company question, then you may just send this as "company" as above, however, if your programme has a managed list of companies, then you must provide the users company details differently and we expect both of the below:

 Custom registration questions

If your programme has custom registration questions, you must send an attribute with a name prefixed with "registration_question_" followed by the id of the custom question to be answered. e.g. <saml:Attribute Name="registration_question_123"> where 123 is the id of the registration question. See documentation for getting registration question id's here or contact your MyRewards administrator if you need further assistance.

Further notes

Whichever field has been set up as your user identifier for your integration should be sent as an attribute with the name specified as your identifier field. For example, if your programme has been set up with username as the user identifier, and uid as the identifier field, then you should send the value in <saml:Attribute Name="uid"> and not <saml:Attribute Name="username">. If you do send <saml:Attribute Name="username"> and that is your user identifier it will be ignored.

OpenID Connect

MyRewards now supports a limited subset of OpenID Connect for SSO. We currently use the "implicit flow", using the ID token-only response type with the form_post response mode. More features from the OpenID Connect specification may be available in the future - please contact your MyRewards representative.

Process flow

  1. User initiates a sign-on request from MyRewards.
  2. MyRewards fetches configuration from the discovery URL provided.
  3. Using the information from (2), MyRewards redirects the user to the authorization endpoint.
  4. User is authenticated by the OpenID Connect provider.
  5. JWT ID token is POST-ed back to MyRewards as a URL-encoded form body.
  6. MyRewards validates the ID token and redirects the user to a holding page whilst profile provisioning is completed via a back channel.
  7. Session established on MyRewards and user is granted access.

Process flow example requests/responses

(2) Fetch configuration from discovery URL:

GET /.well-known/openid-configuration HTTP/1.1
Host: openid-connect-provider.example.com
HTTP/1.1 200 OK
Content-Type: application/json

{
    "issuer": "https://openid-connect-provider.example.com",
    "authorization_endpoint": "https://openid-connect-provider.example.com/authorize",
    "jwks_uri": "https://openid-connect-provider.example.com/jwks",
    "response_types_supported": ["id_token"],
    "subject_types_supported": ["public"],
    "id_token_signing_alg_values_supported": ["RS256"],
    "scopes_supported": ["openid", "email"],
    "response_modes_supported": ["form_post"]
}

(3) Redirect to authorization endpoint:

HTTP/1.1 303 Found
Location: https://openid-connect-provider.com/authorize?response_type=...
GET /authorize?
response_type=id_token
&response_mode=form_post
&client_id=client_id_goes_here
&scope=openid%20email
&redirect_uri=https%3A%2F%2Fmyrewards-programme.example.com%2Fusers%2Fauth%2Fopenid_connect%2Fcallback
&state=random-value-from-myrewards
&nonce=another-random-value-from-myrewards HTTP/1.1
Host: openid-connect-provider.example.com

(5) POST ID token back to MyRewards:

POST /users/auth/openid_connect/callback HTTP/1.1
Host: openid-connect-provider.example.com
Content-Type: application/x-www-form-urlencoded

id_token=jwt.appears.here
&state=random-value-from-myrewards

Second part of JWT:

{
    "iss": "http://server.example.com",
    "sub": "1234567890",
    "aud": "client_id_goes_here",
    "nonce": "another-random-value-from-myrewards",
    "exp": 1311281970,
    "iat": 1311280970,
    "email": "john.doe@email.null"
}

Implementation notes

Configuration discovery

For ease of configuration, and to aid in dynamic configuration changes from the OpenID Connect provider, MyRewards relies on discovery to find most of the configuration values for the provider. To that end, you will need to configure your programme with a "discovery URL", which should be a domain (or domain with a path) that has the path /.well-known/openid-configuration, from which MyRewards will attempt to load the configuration of your OpenID implementation.

This should have the following fields as a minimum (these are all marked as "REQUIRED" by the spec so it is likely your implementation will already have them):

In addition, if the response_types_supported field is included, it should include form_post.

MyRewards does not currently support using WebFinger to obtain the discovery endpoint.

ID token

MyRewards uses the sub field from the ID token as the unique user identifier, and populates the "username" registration question with its value. The email field is also extracted and its value used for the "email" registration question. Due to the dynamic nature of user data on MyRewards, other fields will need to be provided via a side channel (e.g. the update user API).

Next steps

The following information is required to set up OpenID Connect SSO on the MyRewards system:

Further information

For further information on OpenID Connect please refer to the official documentation:

Deprecated End-points

Users (v2)

In order to identify users, a programme will expect to use either username, email or mobile as a unique key to authenticate user with. As a consumer of this service, it is mandatory to supply a value for this field. Furthermore, there will be other fields that have been declared mandatory for your programme and user creation (POST) will fail if these values are not populated or provided.

Create a User

In order to create a user account on the MyRewards 2.0 platform there is often some information about the user we are creating that needs to be known before the account can be successfully created.

Firstly, the user group that the user will be created as a member of must be known, we provide an endpoint to query the usergroups for your programme and if necessary to reconstruct the hierarchy for the usergroups see the usergroups section.

Additionally, user accounts can have extra data required over and above the minimal default fields for a user account. Typically, these take the form of employee data, membership number etc and can be defined as part of your programme. These extra data are called registration_questions, for more information please see the registration_questions section.

Telephone and mobile number fields must be supplied in international format, meaning starting with a '+' followed by the international country code (I.e. the UK is 44) followed by at least 8 numeric characters.

Answers to the registration questions are provided in an array of objects, nested under the key registration_answers_attributes. The nested objects themselves must have the keys registration_question_id and answer. If the question allows multiple answers, then the value for answer should be an array, as show in the example below.

POST /api/v2/users HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "title": "Dr",
    "firstname": "John",
    "lastname": "Doe",
    "username": "john.doe",
    "email": "john.doe@email.null",
    "company": "Org Inc",
    "job_title": "Demo User",
    "address_1": "No 1 The Place",
    "address_2": "The Street",
    "town": "The Town",
    "county": "The County",
    "postcode": "TH3 P057",
    "country": "UK",
    "date_of_birth": "1970-01-01",
    "telephone": "+440000000000",
    "mobile": "+440000000000",
    "chosen_locale": "en",
    "user_group_id": "10",
    "tsandcs": "true",
    "consented": "false",
    "marketing_consented": "true",
    "registration_answers_attributes": [
        {
            "registration_question_id": "2",
            "answer": "Working From Home"
        },
        {
            "registration_question_id": "16",
            "answer": [
                "Monday",
                "Wednesday",
                "Friday"
            ]
        }
    ]
}
HTTP/1.1 201 CREATED
Content-Type: Application/json

{
    "id": 123,
    "title": "Dr",
    "firstname": "John",
    "lastname": "Doe",
    "username": "john.doe",
    "email": "john.doe@email.null",
    "company": "Org Inc",
    "job_title": "Demo User",
    "address_1": "No 1 The Place",
    "address_2": "The Street",
    "town": "The Town",
    "county": "The County",
    "postcode": "TH3 P057",
    "country": "UK",
    "date_of_birth": "1970-01-01",
    "telephone": "+440000000000",
    "mobile": "+440000000000",
    "chosen_locale": "en",
    "user_group_id": "10",
    "tsandcs": "true",
    "consented": "false",
    "marketing_consented": "true",
    "registration_answers_attributes": [
        {
            "registration_question_id": "2",
            "answer": "Working From Home"
        },
        {
            "registration_question_id": "16",
            "answer": [
                "Monday",
                "Wednesday",
                "Friday"
            ]
        }
    ]
}

HTTP Request

POST /api/v2/users

Parameters

Parameters Type Info
username string may be required, see user identification above, must be unique to the programme if required
email string valid email address and may be required, see user identification above, must be unique to the programme if required
title string salutation (Mr, Mrs, Ms, etc) no strict validation.
firstname string Required
lastname string Required
company string Potentially required - see programme data requirements
job_title string Potentially required - see programme data requirements
address_1 string Potentially required - see programme data requirements
address_2 string optional
town string Potentially required - see programme data requirements
postcode string Potentially required - see programme data requirements
county string Potentially required - see programme data requirements
country string Potentially required - see programme data requirements
date_of_birth date must be provided in reverse date format YYYY-MM-DD, Potentially required - see programme data requirements
telephone string Potentially required - see programme data requirements - if supplied must be international format (starting with a '+' followed by international dialling code - UK is 44 - followed by at least 8 numeric characters)
mobile string Potentially required - see programme data requirements, if required, must be unique - if supplied must be international format (starting with a '+' followed by international dialling code - UK is 44 - followed by at least 8 numeric characters)
tsandcs boolean Required
user_group_id integer optional, will default to programme's default user_group, if not provided
registration_answers_attributes array array of hashes that contain a registration_question_id and an answer. Some or all of the registration questions may require answers. See registration_questions endpoint documentation
consented boolean Not required if programme access type is pre_registration with additional details, or SSO or if the programme doesn't have an active privacy policy.
marketing_consented boolean Can be true or false, not required if programme access type is pre_registration with additional details, or SSO or if the programme doesn't have an active privacy policy.

Update a User

The update user api is available to update user information. This uses the same params as the create user api above.

PUT /api/v2/users/{user_id} HTTP/1.1
Authorization: Token token={APIKEY}:{SECRETKEY}
Content-Type: application/json

{
    "user_group_id": "5",
    "registration_answers_attributes": [
        {
            "registration_question_id": "2",
            "answer": "Office"
        },
        {
            "registration_question_id": "16",
            "answer": [
                "Monday",
                "Tuesday",
                "Wednesday",
                "Thursday",
                "Friday"
            ]
        }
    ]
}
HTTP/1.1 200 OK
Content-Type: Application/json

{
    "id": 123,
    "title": "Dr",
    "firstname": "John",
    "lastname": "Doe",
    "username": "john.doe",
    "email": "john.doe@email.null",
    "company": "Org Inc",
    "job_title": "Demo User",
    "address_1": "No 1 The Place",
    "address_2": "The Street",
    "town": "The Town",
    "county": "The County",
    "postcode": "TH3 P057",
    "country": "UK",
    "date_of_birth": "1970-01-01",
    "telephone": "+440000000000",
    "mobile": "+440000000000",
    "chosen_locale": "en",
    "user_group_id": "5",
    "tsandcs": "true",
    "consented": "false",
    "marketing_consented": "true",
    "registration_answers_attributes": [
        {
            "registration_question_id": "2",
            "answer": "Office"
        },
        {
            "registration_question_id": "16",
            "answer": [
                "Monday",
                "Tuesday",
                "Wednesday",
                "Thursday",
                "Friday"
            ]
        }
    ]
}

HTTP Request

PUT /api/v2/users/{user_id}

PATCH /api/v2/users/{user_id}