Points Engine API
This page contains endpoints for additional features that you use to enhance your loyalty program.

Codes

Use this set of endpoints to manage codes that can be given out to users for points or external rewards like airline FFP miles.

Create Code

POST /codes
Create a new code.
We will give you all your campaign_id values.
Fields:
  • value - value of points the code is worth
    • The external reward rate will be calculated based on your settings.
    • eg. if 1 point is 10 miles, then a code of 5 points is worth 50 miles.
  • campaign_id - all the IDs for your campaigns will be provided by us
  • length - optional. Length of the code to generate.
    • Minimum: 9
    • Default: 9
  • email - optional. If an email is passed we will also send the user an email with the code generated. You can choose a template or make a new one. Defaults to null. The email will be validated, failing which, it returns a 400. To send out emails via qiibee, please write to us at [email protected].
  • language - optional. Language for the email. Defaults to en
  • reference_id - optional. type: string.
    • is used as a duplicate check, so if it's sent it always needs to be unique for every request.
    • For example, you could pass your internal receipt/order ID to make sure that one transaction in your system is never processed twice, even if you happen to send the request twice.
eg.
1
{
2
"code": {
3
"value": "100",
4
"campaign_id": 1,
5
"language": "en",
6
"reference_id": "Order 109348HJ61"
7
}
8
}
Copied!
Responses:
  • Success: HTTP 201 and the code:
    • 1
      {
      2
      "data": {
      3
      "code": "719026461",
      4
      "value": "100",
      5
      "campaign_id": 1,
      6
      "reference_id": "Order 109348HJ61"
      7
      }
      8
      }
      Copied!
  • Bad request: HTTP 400
    • eg. Invalid campaign id or Code length too short
  • Conflict: HTTP 409 when reference_id was already used

NFTs

Manage your NFTs and approve/reject user personalisations like engravings and personal messages.

Approve/Reject NFT personalisation

POST /nfts
Use this endpoint to approve or reject a user's NFT personalisation.
If you reject it, the user will receive an email asking them to change the personalisation. You can pick from existing mail templates or create a new one.
All fields are mandatory.
Example request:
1
{
2
"userNFT": {
3
"user_nft_id": "37329",
4
"status": "approved" | "rejected"
5
}
6
}
Copied!

List NFTs Owned By a User

GET /nfts
This endpoint returns a list of NFTs that are owned by a given user. You need to pass in the following query parameters:
  • user_auth_id: (mandatory) the auth_id of the user who owns the NFTs.
  • status: (optional) the status of the NFT. If not sent, it will query the NFTs irrespective of their status. The status can only be one of [null, "pending", "approved", "rejected"].
Example response:
1
{
2
"data": [
3
{
4
"name": "My Test Token",
5
"personalised_data": {"key": "value"},
6
"status": null | "pending" | "approved" | "rejected",
7
"type": "erc721",
8
"user_nft_id": 28
9
},
10
{
11
"name": "My Test Token",
12
"personalised_data": {"key": "value"},
13
"status": null | "pending" | "approved" | "rejected",
14
"type": "erc721",
15
"user_nft_id": 29
16
}
17
]
18
}
Copied!

Rewards

Manage your rewards. Eg. Discount Coupons
Users exchange points for a reward.
Soon you will also be able to send rewards to users dynamically.

Get Reward Details

GET /rewards/:reward
This endpoint will fetch a reward and the associated transaction, used_at, anduser_id if it has already been sent to a user.
Check out the Transactions section of the documentation to see what the loyalty event types are.
Token types
  • erc20 is a regular token
  • erc721 is an NFT token
Token countries
  • AAA represents that the token is operational worldwide.
Responses:
  • Success: HTTP 200 with data in the following format:
1
{
2
"data": {
3
"code": "testcode29",
4
"reward_type": {
5
"id": 1,
6
"locations": [
7
{
8
"id": "2039",
9
"street": "Falkenstrasse",
10
"city": "Zurich",
11
"country": "Switzerland",
12
"zip": "8008",
13
"geolocation": "Geolocation point"
14
}
15
],
16
"metadata": {
17
"coverImage": "https://picsum.photos/id/1025/200/300"
18
},
19
"name": "Online Coupon",
20
"valid_until": "2021-11-23T15:19:19Z",
21
"value": 5,
22
"website": "https://qiibee.com/?extralong_link=verylonglink"
23
},
24
"transaction": {
25
"amount_received": "20.000",
26
"code": null | "GDUTY5F",
27
"exchange_provider": "etihad" | "miles_and_more",
28
"id": 562,
29
"inserted_at": "2021-08-10T15:53:25",
30
"loyalty_event_type": "points_to_rewards",
31
"points_burned": 5,
32
"reward_id": 29,
33
"status": "success",
34
"token": null | {
35
"id": "23421",
36
"address": "0x..3849hz654",
37
"name": "My Token Name",
38
"type": "erc20" | "erc721",
39
"metadata": {
40
"key": "value"
41
},
42
"estimated_member_count_lower": 1000,
43
"estimated_member_count_higher": 5000,
44
"countries": <list_of_ISO3166_country_codes>,
45
"onramp": "24.2" | null,
46
"offramp": "23.5" | null,
47
"status": "active" | "paused" | "pending"| "stopped" | null
48
49
},
50
"tx_hash": "0x.......293dsf23"
51
"used_at": null | "2021-09-28T14:57:49Z",
52
"user": null | {
53
"id": "3r2esf3423r",
54
"email": "[email protected]",
55
"auth_id": "e24c962d-c81c-4a01-b0cd-57dd233553f1",
56
"first_name": "John",
57
"second_name": "Doe",
58
"language": "en",
59
"country_ISO": "usa",
60
"metadata": null | {
61
"opts_newsletter": true | false
62
}
63
}
64
}
65
}
66
}
Copied!
  • Bad data: HTTP 404 with error message
    • eg. not found

Redeem a Reward

PUT /rewards/:reward | PATCH /rewards/:reward
This endpoint is used to mark a reward as used.
We mark it as used by setting the used_at property to the UTC time of the request.
Currently, each reward can be used only once.
Token types
  • erc20 is a regular token
  • erc721 is an NFT token
Token countries
  • AAA represents that the token is operational worldwide.

Responses

  • Success: HTTP 200 with data in the following format:
1
{
2
"code": "SPECIAL20",
3
"used": true,
4
"user": {
5
"id": "3253124153214",
6
"auth_id": "e24c962d-c81c-4a01-b0cd-57dd233553f1",
7
"first_name": "Jane",
8
"second_name": "Doe",
9
"email": "[email protected]",
10
"language": "en",
11
"country_ISO": "usa",
12
"metadata": null | {
13
"opts_newsletter": true | false
14
}
15
}
16
},
17
"reward_type": {
18
"id": 10,
19
"name": "20 EUR Discount",
20
"value": "100",
21
"website": "www.domain.com",
22
"valid_until": "1659515347",
23
"locations": [
24
{
25
"id": "2039",
26
"street": "Falkenstrasse",
27
"city": "Zurich",
28
"country": "Switzerland",
29
"zip": "8008",
30
"geolocation": "Geolocation point"
31
}
32
]
33
},
34
"transaction": {
35
"id": "284798327469",
36
"loyalty_event_type": "points_to_rewards",
37
"exchange_provider": "etihad" | "miles_and_more",
38
"tx_hash": "0x.......293dsf23",
39
"points_burned": "100",
40
"token": null | {
41
"id": "23421",
42
"address": "0x..3849hz654",
43
"name": "My Token Name",
44
"type": "erc20" | "erc721",
45
"metadata": {
46
"key": "value"
47
},
48
"estimated_member_count_lower": 1000,
49
"estimated_member_count_higher": 5000,
50
"countries": <list_of_ISO3166_country_codes>,
51
"onramp": "24.2" | null,
52
"offramp": "23.5" | null,
53
"status": "active" | "paused" | "pending"| "stopped" | null
54
},
55
"status": "success",
56
"reward_id": 3443,
57
"inserted_at": "1627976023"
58
}
59
}
Copied!
  • Conflict: HTTP 409
    • If the reward was already marked as used
  • Bad data: HTTP 404 with error message
    • eg. not found

Transactions

Point to Reward

POST /transactions
The following transaction/loyalty event type is supported to perform this transaction:
  • points_to_rewards - redeem points for a reward like a discount coupon

Redeem Point

All fields are mandatory.
If you try to exchange more points than the user currently has you'll receive a 400.
Body:
  • amount can be an integer or string.
1
{
2
"transaction": {
3
"user_auth_id": "d0d15b76-1928-46bb-9927-8ffbf802455f",
4
"type": "points_to_rewards",
5
"amount": "100",
6
"token_id": 12,
7
"reward_type_id": 2432
8
}
9
}
Copied!

Responses

  • Accepted: HTTP 202
  • Bad Request: HTTP 400
    • eg. unknown transaction type
  • Bad data: HTTP 404 with error message
    • eg. not found

Transaction History

GET /transactions
This request returns paginated transaction history.
By default, it returns the last 100 transactions associated with your brand. The most recent transactions are returned first.
You can query transactions using the following query parameters:
  • limit: (optional) sets the required limit of transaction history to be requested.
    • Defaults: 100
    • Maximum: 100
  • offset: (optional) number of transactions to offset when getting the remaining transactions.
    • Default: 0
  • user_auth_id: (optional) Use this parameter to query transactions for a particular user of your brand. If not passed returns all the transactions for your brand. Can be used along with limit and offset.
  • types: (optional) Use this parameter to query transactions for specific loyalty event types. The events must be sent in a list.
    • Defaults: List of all loyalty event types
  • token_id: (optional) This will let you query the transactions for a specific token ID.
    • Defaults: All tokens that belong to the brand.
The params, limit and offset, work exactly as they’re used in SQL.
Token types
  • erc20 is a regular token
  • erc721 is an NFT token
Token countries
  • AAA represents that the token is operational worldwide.

Responses

  • Success: HTTP 200 with data in the following format:
1
{
2
"data": {
3
"limit": 1,
4
"offset": 0,
5
"total_tx_count": 25,
6
"transactions": [
7
{
8
"amount_received": "1.00000",
9
"code": null,
10
"exchange_provider": "etihad" | "miles_and_more",
11
"id": 706,
12
"inserted_at": "2021-09-27T14:31:10",
13
"loyalty_event_type": "credit_points",
14
"points_burned": null,
15
"reward_id": null,
16
"status": "success",
17
"token": {
18
"id": "3276728",
19
"address": "033Bd49F3ace247112AA6D3d16d24F7Eb5533b17",
20
"metadata": {},
21
"name": "WORKING POINT TOKEN",
22
"estimated_member_count_lower": 1000,
23
"estimated_member_count_higher": 5000,
24
"symbol": "TKN",
25
"type": "erc20" | "erc721",
26
"countries": <list_of_ISO3166_country_codes>,
27
"onramp": "24.2" | null,
28
"offramp": "23.5" | null,
29
"status": "active" | "paused" | "pending"| "stopped" | null
30
},
31
"tx_hash": "0x..xx26",
32
"user": {
33
"auth_id": "9f7326f7-ee-41f4-9c10-aa9f12",
34
"country_ISO": "usa",
35
"email": "[email protected]",
36
"first_name": "Jane",
37
"second_name": "Doe",
38
"id": "NH3HQ==-87b7-2bcd-46ac-b426-0bb81",
39
"language": "en",
40
"metadata": null | {
41
"opts_newsletter": true | false
42
}
43
}
44
45
}
46
]
47
}
48
}
Copied!
If there are no transactions, an empty transactions list will be returned. total_tx_count is the total number of transactions available for the given params.
  • Bad data: HTTP 404 with error message
    • eg. not found