This guide explains how to connect your app to RegoLoop App Tests so that when a tester signs up or completes an action in your product, they get paid instantly - without screenshots or manual checking.
Think of it like this: a tester on RegoLoop sees your App Test: "Sign up on Tunaa and get NGN 4,500". They tap "Accept". RegoLoop gives them a unique link with a secret code baked in, like:
https://yourapp.com/regoloop?rgt=a3f9c2b1e4d7f6c8...When they sign up through that link, your app reads the rgt code and sends it to RegoLoop in the background. RegoLoop sees it, confirms the tasker completed the action, and releases their payout - all in seconds. You don't have to check screenshots. You don't have to approve anything. It just works.
This happens on your server, not the user's browser
Here is the App Test flow, end to end.
Create an App Test, choose the required SDK event names, set your tester slots, and enter your launch URL, for example https://yourdomain.com/regoloop. After approval, the App Test detail page shows the test_run_id, test key, live key, and sandbox tester tokens.
Use test keys first
RTAPP-test or RTAPP-live. Test keys help you confirm wiring without paying real testers.Approval unlocks SDK access
Sandbox tokens avoid tasker setup
https://yourdomain.com/regoloop?rgt=rgt_sandbox_.... You can have 5 active sandbox links at a time, up to 30 total per App Test. Regenerating retires the current 5 and issues the next batch. Sandbox tokens only work with RTAPP-test keys and never complete a real tester session or trigger payout.This is a normal page on your website, such as /regoloop. RegoLoop sends testers there with a ?rgt= token. If the app is installed, the page should open the app. If the app is not installed, show download buttons and tell the tester to open the link again after installing.
https://yourdomain.com/regoloop?rgt=a3f9c2b1e4d7f6c8...Why this page matters
When your app receives the deep link, read the rgt token and save it locally or against the user's session. Keep that value until the tester completes the required action.
const testerToken = new URLSearchParams(window.location.search).get("rgt")
if (testerToken) {
sessionStorage.setItem("regoloop_tester_token", testerToken)
}After your app confirms the action, send test_run_id, event_name, and tester_token to the App Test endpoint.
curl -X POST https://api.live.regoloop.com/api/v1/sdk/v1/events/ \
-H "Authorization: RTAPP-test-yourapp-xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"test_run_id": "paste-your-app-test-id",
"event_id": "signup_completed:user-123",
"event_name": "signup_completed",
"tester_token": "paste-the-rgt-token-from-the-url",
"platform": "web",
"event_time": "2026-07-13T10:00:00Z"
}'RegoLoop receives the event, checks the tester token, confirms the event is required, and updates the App Test event log. Live keys verify real tester sessions.
Your App Test launch URL should be a real page on your own website, for example https://yourdomain.com/regoloop. RegoLoop appends ?rgt=... to that URL. The page exists for two reasons: it lets installed apps open directly, and it gives everyone else a fallback page with install instructions.
What the web page does
rgt token, lets the mobile OS open your app, and shows App Store / Play Store links if the app is not installed. During sandbox testing, this can be a generated rgt_sandbox_... token.What the app does
rgt token from the deep link, saves it, and sends it with the required event after the tester completes the action.// app/regoloop/page.tsx - Next.js fallback page
// RegoLoop launch URL: https://yourdomain.com/regoloop?rgt=...
import Link from "next/link"
export default async function RegoLoopPage({
searchParams,
}: {
searchParams?: Promise<{ rgt?: string }>
}) {
const params = await searchParams
const hasToken = Boolean(params?.rgt)
return (
<main>
<h1>Continue in our app</h1>
<p>
This link opens the app and carries your App Test token. If the app did
not open, install it below and open this link again.
</p>
{!hasToken && <p>No App Test token was found in this link.</p>}
<Link href="https://apps.apple.com/app/your-app">Download on App Store</Link>
<Link href="https://play.google.com/store/apps/details?id=com.yourapp">
Get it on Google Play
</Link>
</main>
)
}// React Native / Expo deep-link capture
// This runs when the tester opens https://yourdomain.com/regoloop?rgt=...
import * as Linking from "expo-linking"
import * as SecureStore from "expo-secure-store"
import { router } from "expo-router"
const TOKEN_KEY = "regoloop_app_test_rgt"
function handleDeepLink(url: string) {
const { hostname, path, queryParams } = Linking.parse(url)
const isAppTestLink =
hostname === "yourdomain.com" &&
path?.split("/").filter(Boolean)[0] === "regoloop"
if (!isAppTestLink) return
const rgt = queryParams?.rgt
if (typeof rgt === "string" && rgt.trim()) {
SecureStore.setItemAsync(TOKEN_KEY, rgt)
}
router.push("/signup")
}
Linking.getInitialURL().then((url) => {
if (url) handleDeepLink(url)
})
Linking.addEventListener("url", (event) => {
handleDeepLink(event.url)
})// iOS: add Associated Domains
applinks:yourdomain.com
applinks:www.yourdomain.com
// Android: add an intent filter for your App Test path
{
"action": "VIEW",
"autoVerify": true,
"data": [
{
"scheme": "https",
"host": "yourdomain.com",
"pathPrefix": "/regoloop"
}
],
"category": ["BROWSABLE", "DEFAULT"]
}
// Website: allow the path in your Apple App Site Association file
{
"applinks": {
"details": [
{
"appID": "TEAMID.com.yourcompany.yourapp",
"paths": ["/regoloop", "/regoloop/*"]
}
]
}
}Keep old links working during migration
App Test events
POST /api/v1/sdk/v1/events/Use with App Test keys that start with RTAPP-test or RTAPP-live. The payload is test_run_id, event_name, tester_token, platform, event_time, and optional event_id. SDK keys and event testing are available only after the App Test has been approved by an admin. Sandbox tester tokens are valid only with test keys.
event_id is optional, but useful for retries
event_id while manually testing if you want every POST to appear as a new received event. Add it in production so retries are idempotent: the same event_id is treated as the same event attempt, while a new real action should get a new event_id. Payout safety does not depend only on event_id: RegoLoop still verifies the tester, test run, and required event before marking a payable completion.# Staging
REGOLOOP_API_URL=https://api.staging.regoloop.com/api/v1
# Production
REGOLOOP_API_URL=https://api.live.regoloop.com/api/v1App Tests use the same rgt token from the launch URL, but they post to the App Test endpoint and use event names such as signup_completed or task_feed_viewed. Test keys log events for dashboard feedback. Live keys verify real tester sessions.
curl -X POST https://api.live.regoloop.com/api/v1/sdk/v1/events/ \
-H "Authorization: RTAPP-test-yourapp-xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"test_run_id": "paste-your-app-test-id",
"event_id": "signup_completed:user-123",
"event_name": "signup_completed",
"tester_token": "paste-the-rgt-token-from-the-url",
"platform": "web",
"event_time": "2026-07-13T10:00:00Z"
}'# pip install regoloop-sdk
from regoloop_sdk import RegoLoop
client = RegoLoop(
api_key="RTAPP-live-yourapp-xxxxxxxxxxxxxxxx",
base_url="https://api.live.regoloop.com/api/v1",
)
client.track_app_test_event(
test_run_id="paste-your-app-test-id",
event_name="signup_completed",
tester_token="token-from-rgt",
platform="web",
)Send events in the background
# Django REST Framework + Celery example
# pip install httpx celery redis
# tasks.py
import httpx
from celery import shared_task
from django.conf import settings
from django.utils import timezone
@shared_task(
bind=True,
autoretry_for=(httpx.RequestError, httpx.HTTPStatusError),
retry_backoff=True,
retry_kwargs={"max_retries": 5},
)
def send_regoloop_app_test_event(self, *, tester_token: str, event_name: str, test_run_id: str):
response = httpx.post(
f"{settings.REGOLOOP_API_URL}/sdk/v1/events/",
headers={
"Authorization": settings.REGOLOOP_LIVE_KEY,
"Content-Type": "application/json",
},
json={
"test_run_id": test_run_id,
"event_id": f"{event_name}:{tester_token}",
"event_name": event_name,
"tester_token": tester_token,
"platform": "web",
"event_time": timezone.now().isoformat(),
},
timeout=10,
)
response.raise_for_status()
# views.py
class SignupView(APIView):
def post(self, request):
# Create the user and finish your normal signup work first.
user = create_user_from_request(request)
tester_token = request.data.get("rgt") or request.data.get("tester_token")
if tester_token:
send_regoloop_app_test_event.delay(
tester_token=tester_token,
event_name="signup_completed",
test_run_id=settings.REGOLOOP_APP_TEST_ID,
)
return Response({"ok": True, "user_id": user.id})Use the test key while building, then switch to the live key after the App Test is approved, funded, and live. The test_run_id is visible on the App Test detail page beside the SDK keys.
1. Copy app run ID
Open the App Test detail page and copy the App run ID.
2. Send a test event
After admin approval, use the RTAPP-test key with a sandbox token. It logs events without real payouts.
3. Switch to live
Use the RTAPP-live key only when real tester sessions should verify.
// React Native / Expo test example
// Use this while wiring your App Test before going live.
import { Platform } from "react-native"
const REGOLOOP_API_URL = "https://api.live.regoloop.com/api/v1"
const REGOLOOP_TEST_KEY = "RTAPP-test-yourapp-xxxxxxxxxxxxxxxx"
const REGOLOOP_APP_TEST_ID = "paste-your-app-test-id"
export async function sendRegoLoopTestEvent({
eventName,
testerToken,
}: {
eventName: string
testerToken: string
}) {
const response = await fetch(`${REGOLOOP_API_URL}/sdk/v1/events/`, {
method: "POST",
headers: {
Authorization: REGOLOOP_TEST_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
test_run_id: REGOLOOP_APP_TEST_ID,
event_id: `${eventName}:${testerToken}`,
event_name: eventName,
tester_token: testerToken,
platform: Platform.OS,
event_time: new Date().toISOString(),
}),
})
const body = await response.json().catch(() => ({}))
if (!response.ok) {
throw new Error(body?.message || "RegoLoop test event failed")
}
return body
}// React Native / Expo live example
// Call this after the real in-app action succeeds.
import { Platform } from "react-native"
const REGOLOOP_API_URL = "https://api.live.regoloop.com/api/v1"
const REGOLOOP_LIVE_KEY = "RTAPP-live-yourapp-xxxxxxxxxxxxxxxx"
const REGOLOOP_APP_TEST_ID = "paste-your-app-test-id"
export async function sendRegoLoopLiveEvent({
eventName,
testerToken,
}: {
eventName: string
testerToken: string
}) {
const response = await fetch(`${REGOLOOP_API_URL}/sdk/v1/events/`, {
method: "POST",
headers: {
Authorization: REGOLOOP_LIVE_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
test_run_id: REGOLOOP_APP_TEST_ID,
event_id: `${eventName}:${testerToken}`,
event_name: eventName,
tester_token: testerToken,
platform: Platform.OS,
event_time: new Date().toISOString(),
}),
})
const body = await response.json().catch(() => ({}))
if (!response.ok) {
throw new Error(body?.message || "RegoLoop live event failed")
}
return body
}Keep live keys out of public builds
When a tester opens your App Test launch URL, RegoLoop passes a unique token just for them. This token is embedded in their referral link as ?rgt=. You don't need to generate or store it - it comes from the URL.
For brand-side testing, use a sandbox tester token from the App Test detail page. RegoLoop gives you a launch URL like https://yourdomain.com/regoloop?rgt=rgt_sandbox_.... Open that URL, let your app capture the rgt, then send it as tester_token with an RTAPP-test key.
Add these to your server's .env file:
# Your App Test API keys
REGOLOOP_APP_TEST_ID=paste-your-app-test-id
REGOLOOP_TEST_KEY=RTAPP-test-yourapp-xxxxxxxxxxxxxxxx
REGOLOOP_LIVE_KEY=RTAPP-live-yourapp-xxxxxxxxxxxxxxxx
# Base URL
# Staging: https://api.staging.regoloop.com/api/v1
# Live: https://api.live.regoloop.com/api/v1
REGOLOOP_API_URL=https://api.live.regoloop.com/api/v1Create your App Test, get your API keys, and verify your first test event.