Content Creators
Rewards API Integrations

Rewards API Integrations

This section explains how to integrate Rewards with your scene, server, or quests.

With your scene #

Rewards can be integrated directly into Decentraland scenes. This exposes all the logic in code that is accessible to the user, so it is not recommended for minting items with a rarity lower than EPIC . Consider the possibility that users possessing adequate knowledge and time could potentially solve captchas, alter their IP addresses, and subsequently mint all the available items, ultimately selling them on the marketplace. The only real incentive to prevent this is having enough items to mint to ensure that everyone is getting a wearable/emote.

The following measures are recommended to reduce the risk of exploits in this scenario:

Example #

import { getPlayer } from '@dcl/sdk/src/players'
import { signedFetch } from '@decentraland/SignedFetch'
import { getRealm } from '~system/Runtime'

export function main() {
  // 1. Get captcha challenge to show to the user
  const request = await fetch(`https://rewards.decentraland.org/api/captcha`, {
    method: 'POST',
  })
  const captcha = await request.json()
  console.log('CAPTCHA DATA: ', captcha)

  // Response:
  //
  // {
  //   "ok": true,
  //   "data": {
  //     "width": 300,
  //     "height": 100,
  //     "id": "9e6b2d07-b47b-4204-ae87-9c4dea48f9b7",
  //     "expires_at": "2023-11-08T12:49:44.457Z",
  //     "image": "https://rewards2-assets-prd-05e0ac2.decentraland.org/catpcha/9e6b2d07-b47b-4204-ae87-9c4dea48f9b7.png"
  //   }
  // }

  // 2. Display captcha for player to complete
  // See example in studios.decentraland.org/resources

  // 3. Get user data
  const user = getPlayer()

  // 4. Get current realm
  const realmInfo = await getRealm({})

  // 5. Send request to assign a wearable/emote
  const assignRequest = await signedFetch('https://rewards.decentraland.org/api/rewards', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      campaign_key: '[DISPENSER_KEY]', // dispenser key
      beneficiary: user.userId, // ethereum address
      catalyst: realmInfo.baseUrl, // catalyst domain
      captcha_id: captcha.data.id, // "9e6b2d07-b47b-4204-ae87-9c4dea48f9b7"
      captcha_value: '[CAPTCHA_VALUE]', // "123456"
    }),
  })

  const reward = await assignRequest.json()
  console.log(reward)

  // Response:
  //
  // {
  //   ok: true,
  //   data: [
  //     {
  //       id: '00000000-0000-0000-0000-000000000000',
  //       user: '0x0f5d2fb29fb7d3cfee444a200298f468908cc942',
  //       campaign_id: '00000000-0000-0000-0000-000000000000',
  //       campaign_key: "[DISPENSER_KEY]",
  //       status: 'assigned',
  //       chain_id: 137,
  //       airdrop_type: 'CollectionV2IssueToken',
  //       target: '0x7434a847c5e1ff250db456c55f99d1612e93d6a3',
  //       value: '0',
  //       group: null,
  //       priority: 2144355453,
  //       transaction_id: null,
  //       transaction_hash: null,
  //       token: 'Polygon sunglasses',
  //       image:
  //         'https://peer.decentraland.zone/lambdas/collections/contents/urn:decentraland:amoy:collections-v2:0x7434a847c5e1ff250db456c55f99d1612e93d6a3:0/thumbnail',
  //       assigned_at: '2021-09-24T01:30:16.770Z',
  //       created_at: '2021-09-24T01:25:14.534Z',
  //       updated_at: '2021-09-24T01:25:14.534Z',
  //     }
  //   ]
  // }
}

With Quest the service #

You can easily integrate Rewards with the Quests service , this is ideal if you want to reward users for completing a quest.

The following measures are recommended to reduce the risk of exploits in this scenario:

Any other of the other flags will make your integration fail, avoid using them.

⚠️ The dispenser key should be kept secret, so you should never expose it to the user at anytime.

Example #

To integrate your Quest with the Rewards service, you just need a dispenser key and to configure a webhook to receive the rewards.

{
    // ...
    "reward": {
        "hook": {
            "webhookUrl": "https://rewars.decentraland.org/api/rewards",
            "requestBody": {
                "campaign_key": "[DISPENSER_KEY]",
                "beneficiary": "{user_address}"
            }
        },
        // ...
    }
}

With a custom server #

You can integrate Rewards directly from your server, this is ideal for carrying out extra checks before minting items. Another benefit is that users never have contact with the code on your server, making it harder to find vulnerabilities.

The following measures are recommended to reduce the risk of exploits in this scenario:

Any of the other flags will make your integration more complex or, depending on your use case, can make it fail, so we don’t recommend using them, but you may consider taking advantage of them.

⚠️ The dispenser key should be kept secret, so you should never expose it to the user at anytime.

Example #

const request = await fetch('https://rewards.decentraland.org/api/rewards', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    campaign_key: '[DISPENSER_KEY]',
    beneficiary: '0x0f5d2fb29fb7d3cfee444a200298f468908cc942', // ethereum address
  }),
})

const response = await request.json()
console.log(response)

// Response:
//
// {
//   ok: true,
//   data: [
//     {
//       id: '00000000-0000-0000-0000-000000000000',
//       user: '0x0f5d2fb29fb7d3cfee444a200298f468908cc942',
//       campaign_id: '00000000-0000-0000-0000-000000000000',
//       campaign_key: "[DISPENSER_KEY]",
//       status: 'assigned',
//       chain_id: 137,
//       airdrop_type: 'CollectionV2IssueToken',
//       target: '0x7434a847c5e1ff250db456c55f99d1612e93d6a3',
//       value: '0',
//       group: null,
//       priority: 2144355453,
//       transaction_id: null,
//       transaction_hash: null,
//       token: 'Polygon sunglasses',
//       image:
//         'https://peer.decentraland.zone/lambdas/collections/contents/urn:decentraland:amoy:collections-v2:0x7434a847c5e1ff250db456c55f99d1612e93d6a3:0/thumbnail',
//       assigned_at: '2021-09-24T01:30:16.770Z',
//       created_at: '2021-09-24T01:25:14.534Z',
//       updated_at: '2021-09-24T01:25:14.534Z',
//     }
//   ]
// }