The points API
All points changes over the API are done through the v3/point-accounts endpoints.
Note
One use of the points API is when Engage is acting as point follower. See here for more on this.
Terms and parameters
Some terms and parameters are useful to know before going into detail:
Point definitions: The "type" of points. Currently one point definition exists but the system allows for different kinds of points to be tracked in parallel, each with their own point definition value. The parameter is definitionId.
Point accounts: Points of different types are separated by their point definition value. This allows contacts to have many independent point totals and histories (accounts) each uniquely defined by a contact ID plus a definition ID. Parameter is accountId.
Point transactions: A transaction or an update to a transaction specifying the change to a contact's points.
Active points: The points that a contact currently owns which can be used to create vouchers.
Pending points: Points with a validFrom date in the future, that will not become active until then.
The offset and count parameters: Optional, can be used to pagination the results.
The filter parameter: Can be "All", "Active", "Pending" or left blank. Used to return active points, pending points, or both.
Changes from v2 to v3
Several changes were made in these endpoints for v3. See the full list here.
Important
One important change is that in v3 a contact's total points (bonus points) are no longer returned from /contactoverview. This can now only be done through a separate GET request to the already existing but slightly changed /point-accounts endpoint. See the following section for details.
Getting point accounts
To get all of a contact's point accounts, use this endpoint:
GET api/v3/point-accounts
You send the contactId as a query string parameter. This returns all point accounts like this:
{ "links": [], "count": 2, "offset": 0, "items": [ { "balance": 110, "balanceExpires": "2023-08-14T13:03:52.0510384+02:00", "contactId": "efaaefb8-e07a-46d5-89fa-1423e87b0798123111", "definitionId": 1, "id": 9, "pendingPoints": 0, "links": [ { "id": 1, "href": "https://yoururl/api/v3/point-accounts/definitions/1", "method": "GET", "rel": "definition" }, { "href": "https://yoururl/api/v3/point-accounts/transactions?accountId=9", "method": "GET", "rel": "transactions" } ] }, { "balance": 110, "balanceExpires": "2023-08-14T13:03:52.0510384+02:00", "contactId": "efaaefb8-e07a-46d5-89fa-1423e87b0798123111", "definitionId": 2, "id": 9, "pendingPoints": 0, "links": [ { "id": 1, "href": "https://yoururl/api/v3/point-accounts/definitions/1", "method": "GET", "rel": "definition" }, { "href": "https://yoururl/api/v3/point-accounts/transactions?accountId=9", "method": "GET", "rel": "transactions" } ] } ], "totalCount": 2 }
If you know the unique ID of the point account, you can get the information directly by using the ID in the path. For example:
GET api/v3/point-accounts/fa1de1de-427d-4a63-8f43-513fc8b5e97b
Which returns the following:
{ "balance": 110, "balanceExpires": "2023-08-14T13:03:51.9719335+02:00", "contactId": "af687249-b52a-4926-8591-ccf881b59e9e", "definitionId": 1, "id": 1234567899, "pendingPoints": 0, "links": [ { "id": 1, "href": "https://yoururl/api/v3/point-accounts/definitions/1", "method": "GET", "rel": "definition" }, { "href": "https://yoururl/api/v3/point-accounts/transactions?accountId=9", "method": "GET", "rel": "transactions" } ] }
The links section contains optional information with some useful API calls you can use.
Getting point transactions
Now you know the unique point account ID (which you got in the previous step) you can fetch a list of all transactions that have generated, removed or adjusted points for that account, using:
GET api/v3/point-transactions
Send the point account ID in the query string as the parameter id.
There are some optional parameters you can use to filter the results:
The parameters offset and count can be used to paginate the results.
The parameter filter can also be used to fetch active points, pending points or both.
The parameter sortBy lets you sort the results on transaction date or created-on date.
With sortOrder you can order results in ascending or descending order.
As an example. this request returns all pending points transactions for the given point account ID:
GET api/v3/point-transactions?id=55579bfd-718a-496e-bd80-50e5ec5b0d2b145&filter=pending
Point transactions descriptions
In the payload returned from /point-transactions you'll see a "description" field:
Important
Note that this functionality has changed somewhat in API v3.
{ "items": [ { "id": "be5abf92-98ac-4192-b0c3-af7da42fbb5a", "accountId": "1096a160-af33-4f4f-b78a-5ddc284451af", "description": "@@(Bonus.Points) - Slim Fit T-shirt", "source": "Purchase", "amount": 719.7, "type": "Addition", ... }, { "id": "12548f57-fbdf-1234-8b14-de9e30ce5e3a", "accountId": "2222a160-af60-4f4f-b78a-5ddc284451af", "description": "@@(ConvertedToBonusCheck)", "source": "RewardVoucher", "amount": -15000, "type": "Deduction", ... }, { "id": "f5d27525-918c-4fb2-a71e-c90f5efbff09", "accountId": "7777a160-af60-4f4f-b78a-5ddc284451af", "description": "Plus member - extra points for purchase (45 points) - Regular Fit Sweatshirt", "source": "BonusPromotion", "amount": 449.85, "type": "Addition", ... } ], "totalCount": 2, "offset": 0, "count": 2, "links": [] }
Some description values contain a code, such as the @@(ConvertedToBonusCheck) seen in the example above. These codes are placeholders for a certain type of description, and for each one you can set up your implementation to use a text to explain the transaction. For example, on a contact's My Pages.
To help you with that, here are explanations along with suggested descriptions:
Code | Usage | Example description |
---|---|---|
@@(Bonus.Points) | When points are awarded for a purchase. | "Points awarded from purchase." |
@@(RemovedDueToTimeLimit) | When points have passed their expiry date and can no longer be used. | "Deduction for expired points." |
@@(Bonus.DeductionForDiscount) | When points are removed because of the price being discounted. | "Deduction for discount." |
@@(Bonus.DeductionForReturn) | When points are removed because of a return being made. | "Deduction for returned item." |
@@(ConvertedToBonusCheck) | When points are removed because they have been converted to a voucher. | "Points converted to voucher." |
You will need to handle this manually in your frontend, using either the texts suggested in the table, or your own customized version of them, whichever suit your needs.
Adding a single point transaction
To add a single points transaction to a points account, this is the recommended, more robust and faster option.
POST /api/v3/point-transactions
Tip
To add multiple points transactions at once, to the same or to different point accounts, you can use the bulk endpoint /api/v3/point-accounts/transactions which is covered in the following section.
The data sent in the request body has the following structure:
{ "accountId": "00000000-0000-0000-0000-000000000000", "transactionId": "00000000-0000-0000-0000-000000000000", "transactionType": "Addition", "amount": 0, "description": "string", "source": "Automation", "transactionDate": "2024-11-13T08:16:27.949Z", "validFrom": "2024-11-13T08:16:27.949Z", "validTo": "2024-11-13T08:16:27.949Z" }
accountId: The unique ID of the points account you are adding points to.
transactionId: This value you will need to send in. If this transaction is coming from, for example, your e-com, then there is already a unique ID that you can use. Or you can create one and store it your own database as a reference.
Adding several point transactions at once
To batch add point transactions to Engage, or adjust existing points, use this endpoint.
POST api/v3/point-accounts/transactions
The transaction data is sent in the request body, in this JSON format:
[ { "contactId": "111111fa6-103b-459b-8d01-b6c000e8e26a", "amount": 12, "definitionId": 1, "timeStamp": "2023-06-01T08:40:51.658Z", "source": "Purchase", "description": "Gilded gauntlets", "validFrom": "2023-06-16T08:40:51.658Z", "validTo": "2024-06-16T08:40:51.658Z" } ]
Many transactions can be sent in this array, up to a maximum of 1000.
The points amount (12 in this case) will be added to the point account defined by this contact ID and definition ID. If no point account exists for that contact ID and definition ID, then one will be created and used.
Common values for source are "Purchase", "Adjustment" and "Return". Other values are also available.
Since the points in this example have a validFrom date that's in the future from the purchase date, these points will be pending until then. When that date arrives, they will change to active.
A successful POST to this endpoint gets a HTTP 202 Accepted response. Otherwise you'll get:
400 Too many items, New point system not active
Getting a specific transaction
You can fetch the information for a specific point transaction if your know its unique transaction ID:
GET api/v3/point-transactions/{id}
This returns the transaction with that ID (assuming it exists) in the following format:
{ "accountId": 1, "amount": 800, "createdOn": "2022-11-16T13:17:54+00:00", "description": "Some text", "id": 1, "modifiedOn": "2022-12-16T00:05:21+00:00", "source": "Adjustment", "transactionDate": "2022-11-16T14:17:54+01:00", "type": "Adjustment", "validFrom": "2016-11-16T14:17:54+01:00", "validTo": "2017-11-16T23:59:59+01:00", "retailTransactionLineItemId": "d5ad8be8-6785-4922-95fe-b12500d3ff91" "links": [ ... ] }
Note
The value of retailTransactionLineItemId allows you to link this particular point transaction back to the exact line item that caused it.