Overview
Callbacks (also called postbacks) allow TapResearch to notify your web service when:
- Users receive rewards
- The SDK successfully initializes (in-app only)
TapResearch supports two callback types (choose one per app):
- In-app callbacks - Default method
- Server-to-server callbacks - Requires custom configuration
In-App Callbacks
In-app callbacks report rewards as a collection in a single RewardCollection callback.
Example: If a user completes three surveys, the SDK fires one callback containing all three rewards.
Key features:
- TapResearch notifies users of their rewards
- Default callback method (fires unless server-to-server is configured)
When callbacks fire:
- When the user closes TapResearch
- After successful SDK initialization
Server-to-Server Callbacks
Server-to-server callbacks are fired immediately after a user earns a reward.
Important: Your app must notify users of rewards received (TapResearch does not notify users with this method).
By default, server-to-server callbacks use GET requests.
Update Callback URL
Update your callback URL in the "Edit App" section of the Publisher Dashboard.

URL Validation
Requirements:
- No spaces or special characters
- Must return a 2xx response code to be considered valid
Callback Testing
Use the Test Callback button to generate a test completion that fires a callback to your specified URL.
Best practice: Test callbacks before deploying to production.
Test callbacks use fixed currency values. Commercial survey values will vary.
Sample Callback Requests
GET Request
https://tapresearch.com/postback?api_token=your-server-api-token&cpid=
tap_37939e4ede350f3a8d5149d2fcaa025e&did=0258DE71-DFEB-4399-BF26-11C1F6E600D2&payout
_amount=191&payout_currency=gold&revenue=0.5&tid=777ca23551a4a9173920c22e1ed7f4f3&uid
=developers%40tapresearch.com&sig=b438afd7426c743e777c387d7e2712d4
POST Request
Note: Contact developers@tapresearch.com to enable POST requests.
URL:
https://tapresearch.com/postback?api_token=your-server-api-token
JSON Body
{
"uid": "developers",
"did": "0258DE71-DFEB-4399-BF26-11C1F6E600D2",
"tid": "777ca23551a4a9173920c22e1ed7f4f3",
"cpid": "tap_37939e4ede350f3a8d5149d2fcaa025e",
"api_token": "the api token found in your settings",
"payout_amount": 191,
"payout_currency": "gold",
"revenue": 0.5,
"payout_type": 3,
"ip_address": "10.0.0.1",
"sig": "b438afd7426c743e777c387d7e2712d4"
}
Payload
Parameter | Type | Description |
---|---|---|
uid | String | Persistent unique identifier for this user. |
did | String | Device identifier -- IDFA for Apple, Google Device ID for Android (May not be present if the user opted out of ad tracking). |
tid | String | Transaction ID or click ID. This value will not be unique if the user completed multiple surveys in a single session. Use cpid for deduping purposes. |
cpid | String | Unique survey complete identifier. We recommend that you store and check against this value to ensure you reward the user only once per survey complete. |
api_token | String | This is the unique identifier we generate when you create an app in our dashboard. |
payout_amount | Integer | Amount of currency earned by this user. |
payout_currency | String | The type of Currency the user earned. |
revenue | Decimal | Amount you will be paid for this survey complete in USD. |
payout_type | Integer | The action that the user was rewarded for. 0 - Profile Complete, 3 - Survey Rewarded, 9 - Quick Question Completed. |
ip_address | String | This is the IP address of the respondent when the transaction occurred. |
sig | String | This is the URL signature, which is an HMAC-MD5 generated using the query string, minus the sig parameter. See the security section for more details. |
Security
For security purposes, every callback request will include an HMAC-MD5, which is generated using the query string. Using the example request in the callback section, here are the steps to generate the HMAC-MD5. Grab your API secret. This value is located in your main dashboard. Example: 26dcc0fc7b6208fdfeffaf19f627cb4a
- A callback request will look similar to the example shown below: https://tapresearch.com/postback?api_token=9b99ccc0062035544a5b6579b0cfc954&cpid=tap_37939e4ede350f3a8d5149d2fcaa025e&did=0258DE71-DFEB-4399-BF26-11C1F6E600D2&payout_amount=191&revenue=0.5&tid=777ca23551a4a9173920c22e1ed7f4f3&uid=developers%40tapresearch.com&sig=b438afd7426c743e777c387d7e2712d4
- Isolate the query string, leaving out the question mark. Example:
api_token=9b99ccc0062035544a5b6579b0cfc954&cpid=tap_37939e4ede350f3a8d5149d2fcaa025e&did=0258DE71-DFEB-4399-BF26-11C1F6E600D2&payout_amount=191&revenue=0.5&tid=777ca23551a4a9173920c22e1ed7f4f3&uid=developers%40tapresearch.com&sig=b438afd7426c743e777c387d7e2712d4
- Strip out the
sig
parameter, including the ampersand (&) symbol. Example:api_token=9b99ccc0062035544a5b6579b0cfc954&cpid=tap_37939e4ede350f3a8d5149d2fcaa025e&did=0258DE71-DFEB-4399-BF26-11C1F6E600D2&payout_amount=191&revenue=0.5&tid=777ca23551a4a9173920c22e1ed7f4f3&uid=developers%40tapresearch.com
- Decode the query string. Example:
api_token=9b99ccc0062035544a5b6579b0cfc954&cpid=tap_37939e4ede350f3a8d5149d2fcaa025e&did=0258DE71-DFEB-4399-BF26-11C1F6E600D2&payout_amount=191&revenue=0.5&tid=777ca23551a4a9173920c22e1ed7f4f3&uid=developers@tapresearch.com
- Run the API secret and the modified payload through your favorite HMAC-MD5 generator. Using the example values in steps 1 and 2, the resulting string will be
b438afd7426c743e777c387d7e2712d4
. - Check your generated HMAC against the
sig
param value. If they match, then record a complete and reward the user.
- Ruby
- PHP
- Java
# Sample request URL
url = "https://tapresearch.com/postback?api_token=9b99ccc0062035544a5b6579b0cfc954&cpid=tap_37939e4ede350f3a8d5149d2fcaa025e&did=0258DE71-DFEB-4399-BF26-11C1F6E600D2&payout_amount=191&revenue=0.5&tid=777ca23551a4a9173920c22e1ed7f4f3&uid=developers%40tapresearch.com&sig=b438afd7426c743e777c387d7e2712d4"
# Isolate query string
query_string = url.gsub(/^(.*?)\?/, "")
# Strip out the sig parameter
stripped_query_string = query_string.gsub(/&sig.*/, "")
# Decode URL
decoded = URI.decode(stripped_query_string)
# Generate HMAC-MD5
api_secret = "26dcc0fc7b6208fdfeffaf19f627cb4a"
digest = OpenSSL::Digest.new("md5")
md5 = OpenSSL::HMAC.hexdigest(digest, api_secret, decoded)
puts md5 # b438afd7426c743e777c387d7e2712d4
<?php
# Sample request URL
$url = 'https://tapresearch.com/postback?api_token=9b99ccc0062035544a5b6579b0cfc954&cpid=tap_37939e4ede350f3a8d5149d2fcaa025e&did=0258DE71-DFEB-4399-BF26-11C1F6E600D2&payout_amount=191&revenue=0.5&tid=777ca23551a4a9173920c22e1ed7f4f3&uid=developers%40tapresearch.com&sig=b438afd7426c743e777c387d7e2712d4';
# Isolate query string
$query_string = parse_url($url, PHP_URL_QUERY);
# Strip out the sig parameter
$stripped_query_string = substr($query_string, 0, strpos($query_string, 'sig') - 1);
# Decode URL
$decoded = urldecode($stripped_query_string);
# Generate HMAC-MD5
$api_secret = '26dcc0fc7b6208fdfeffaf19f627cb4a';
$md5 = hash_hmac('md5', $decoded, $api_secret);
echo $md5; #b438afd7426c743e777c387d7e2712d4
?>
private static final String API_SECRET = "26dcc0fc7b6208fdfeffaf19f627cb4a";
private static final String ALGO = "HmacMD5";
try {
// URL
String urlString = "https://tapresearch.com/postback?api_token=9b99ccc0062035544a5b6579b0cfc954&cpid=tap_37939e4ede350f3a8d5149d2fcaa025e&did=0258DE71-DFEB-4399-BF26-11C1F6E600D2&payout_amount=191&revenue=0.5&tid=777ca23551a4a9173920c22e1ed7f4f3&uid=developers%40tapresearch.com&sig=b438afd7426c743e777c387d7e2712d4";
// Generate HAMC-MD5
Mac mac = Mac.getInstance(ALGO);
SecretKeySpec key = new SecretKeySpec(API_SECRET.getBytes(StandardCharsets.UTF_8), ALGO);
mac.init(key);
// Isolate query string and remove sig parameter
String queryString = urlString.substring(urlString.indexOf("?") + 1);
queryString = queryString.substring(0, queryString.indexOf("&sig=")) + queryString.substring(queryString.indexOf("&sig=") + 25);
// Decode URL
String decode = URLDecoder.decode(queryString, StandardCharsets.UTF_8);
byte[] bytes = mac.doFinal(decode.getBytes(StandardCharsets.UTF_8));
String md5 = DatatypeConverter.printHexBinary(bytes).toLowerCase();
System.out.println(md5); // b438afd7426c743e777c387d7e2712d4
} catch (Exception e) {
e.printStackTrace();
}
Retries
If a callback fails, our system will continue retrying to send the reward for 48 hours OR until a 2xx response code is returned.
Callback Visualization
