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
- a valid user
- it is a user for the programme that your api key is scoped to.
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
- a valid user
- it is a user for the programme that your api key is scoped to.
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:
- The field is an identifier (email, username)
- The field is hidden from users so they cannot update this when additional details are requested
- Your programme is not set to require additional details from users, therefore all mandatory fields must be supplied upon creation
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 |
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 |
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:
GET /api/v3/users/{id}
GET /api/v3/users/email/{email}
GET /api/v3/users/username/{username}
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
- User is challenged to authenticate at the IdP side
- User Logs in to the IdP
- User selects access to SP
- IdP Responds with assertion to user
- User's browser
POST
s this assertion to the MyRewards programme - 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:
- user's email address - as recorded on MyRewards Programme
- username - as recorded on MyRewards Programme
- unique identifier/primary key for the user as recorded in MyRewards Programme
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:
- URL of the identify provider
- Fingerprint of X.509 certificate – this can be extracted from the public key
- URL access redirect
- Failed log in redirect (if not included in the assertion)
- User identifier (id, email or username)
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 |
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:
- user's email address - as recorded on MyRewards Programme
- username - as recorded on MyRewards Programme
- unique identifier/primary key for the user as recorded in MyRewards Programme
The following standard user fields may be provided as an attributes Name value e.g. <saml:Attribute Name="firstname">
:
- username
- title
- firstname
- lastname
- job_title
- address_1
- address_2
- town
- postcode
- county
- country
- date_of_birth
- telephone
- mobile
- chosen_locale
- tsandcs
- consented
- marketing_consented
- user_group_id
- company (depending on the configuration of your programme - see below)
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:
- company_name
- company_identifier
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
- User initiates a sign-on request from MyRewards.
- MyRewards fetches configuration from the discovery URL provided.
- Using the information from (2), MyRewards redirects the user to the authorization endpoint.
- User is authenticated by the OpenID Connect provider.
- JWT ID token is
POST
-ed back to MyRewards as a URL-encoded form body. - MyRewards validates the ID token and redirects the user to a holding page whilst profile provisioning is completed via a back channel.
- 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):
issuer
authorization_endpoint
jwks_uri
response_types_supported
- should includeid_token
subject_types_supported
- should includepublic
id_token_signing_alg_values_supported
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:
- Discovery URL - as described above
- Client ID
- Client secret
- A URL to redirect users on login failure (this is typically a content page on the MyRewards programme itself)
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 |
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}