Testerup Data API: Wallet, Task Progress & Payout Fields
Testerup: Test & Earn Rewards is aestimium GmbH's Android app for earning rewards through paid testing. The Hamburg company (Rödingsmarkt 39, 20459, managing director Paul Schempp, HRB 144566) lets members aged 18+ sign up free with email or Google/Apple, then earn by playing mobile games, taking surveys, and testing apps and websites for advertising partners. Typical tasks are advertised as taking 15–20 minutes; members choose offers from the home feed, follow their progress in My Tasks, check earnings in the wallet and request withdrawals through a payout form. US members cash out in USD via PayPal, Amazon gift card, virtual Visa or Venmo once the wallet reaches a published threshold ($60 / $75 / $100 and up); UK options are PayPal, Amazon gift card or virtual Visa in GBP, while Canadian members use the same threshold ladder in CAD. The Play listing is rated 4.0 from about 132,000 reviews and was last updated on 28 September 2026 (client 3.2.10); the site claims more than 28.7 million activated users and a Trustpilot score around 4.2. It competes with Freecash-style rewarded-task apps rather than banking services.
Testerup reward records distinguish available wallet balance, pending openPayoutAmount and lifetime totalPaidOut. The member object adds customerNumber, registrationCountry, currencyCode, the payoutThresholds ladder and paymentOptions, whose method and feeRate describe channels such as PAYPAL, AMAZON_GIFT_CARD, VENMO and VISA_VIRTUAL_CARD and their fees. Payout records carry paymentProvider, netAmount, status and createdAt; a linked PayPal identity has its own identifier. Together these fields let treasury teams build reconciliation views that keep outstanding payouts separate from completed payments. Verification fields faceScanVerification, isVerified and maxAttemptsReached also support eligibility checks where face verification is required.
Offer records describe title, reward amount and currencyCode, with goal displayName, isInAppPurchase, isTimeGated and timeLimitHours. Started tasks add goalConversions, goalId, status and reward, distinguishing PENDING goals from CREDITED ones. Task detail includes expiresAt, nextDecayAt, nextReward, purchaseValue and cashbackRatioPercentage for tracking deadlines, changing rewards and purchase-related cashback. Reward analytics teams can compare goal terms with conversion progress without counting pending goals as available wallet funds.
Survey entries pair surveyDuration with reward, while account-streak records supply currentDay, milestoneIntervalDays, isTodayCounted, resetsAt, minEarning, maxDailyReward, pendingRewards and eligibleGames. Referral records add referralCount, invite code and valueTier. Operations teams can build survey reward comparisons, streak-status views and referral tracking alongside the wallet and task records. openData Studio turns these documented fields into callable open data for reward tracking and payout reconciliation.
Screenshots
API surface
Request/response examples are illustrative, reconstructed from the app's interface — not a live capture.
Email login and 2FA challenge
POST
/graphql/osintSigns the member in on the Sign in screen and either mints the Bearer pair or opens the email OTP challenge used by the /2fa web-app route.
Auth: Unauthenticated. operationName=Login. On success returns accessToken and refreshToken; when two-factor is on, a challengeId plus maskedEmail must be finished with TwoFactorSignIn before Me calls accept Authorization: Bearer.
- login
- success
- accessToken
- refreshToken
- twoFactor
- challengeId
- maskedEmail
- expiresAt
- resendAvailableAt
- lockedUntil
POST /graphql/ HTTP/1.1 Content-Type: application/json Accept: application/graphql-response+json, application/json { "operationName": "Login", "query": "mutation Login($userData: LoginInput!) { login(userData: $userData) { success credentials { accessToken refreshToken } twoFactor { challengeId maskedEmail expiresAt resendAvailableAt lockedUntil } } }", "variables": { "userData": { "email": "[email protected]", "password": "********" } } }{ "data": { "login": { "success": true, "error": null, "credentials": { "accessToken": "eyJhbGciOi...", "refreshToken": "rt_8f21..." }, "twoFactor": { "challengeId": "2fa-4401", "maskedEmail": "m***@example.com", "expiresAt": "2026-10-23T13:05:00Z", "resendAvailableAt": "2026-10-23T12:51:00Z", "lockedUntil": null } } } }Signed-in member, wallet and payout rails
POST
/graphql/openfinanceHydrates the profile chip and wallet page: spendable balance versus openPayoutAmount, lifetime totalPaidOut, the published payoutThresholds ladder, and paymentOptions method/feeRate (PAYPAL, AMAZON_GIFT_CARD, VENMO, VISA_VIRTUAL_CARD).
Auth: Bearer accessToken from Login, OAuthLogin or AppleOAuthLogin. operationName=Me.
- me
- id
- customerNumber
- registrationCountry
- currencyCode
- payoutThresholds
- balance
- openPayoutAmount
- totalPaidOut
- paymentOptions
- method
- feeRate
- countryCode
- faceScanVerification
- isVerified
- referralCount
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json Accept: application/graphql-response+json, application/json { "operationName": "Me", "query": "query Me { me { success user { id firstName lastName email customerNumber registrationCountry currencyCode payoutThresholds wallet { balance openPayoutAmount totalPaidOut } paymentOptions { method feeRate } profile { countryCode postcode cityRegion } faceScanVerification { isVerified isDuplicate maxAttemptsReached } referralCount referralMaxReferrals } } }" }{ "data": { "me": { "success": true, "user": { "id": "u-88421", "firstName": "Maya", "lastName": "Keller", "email": "[email protected]", "customerNumber": "CN-229184", "registrationCountry": "US", "currencyCode": "USD", "payoutThresholds": [60, 75, 100, 150, 250, 500], "wallet": { "balance": 84.5, "openPayoutAmount": 12.0, "totalPaidOut": 240.0 }, "paymentOptions": [ { "method": "PAYPAL", "feeRate": 0 }, { "method": "AMAZON_GIFT_CARD", "feeRate": 0 }, { "method": "VENMO", "feeRate": 0 }, { "method": "VISA_VIRTUAL_CARD", "feeRate": 0.02 } ], "profile": { "countryCode": "US", "postcode": "85001", "cityRegion": "Arizona, Phoenix" }, "faceScanVerification": { "isVerified": true, "isDuplicate": false, "maxAttemptsReached": false }, "referralCount": 3, "referralMaxReferrals": 10 } } } }Home offer suggestions
POST
/graphql/opendataFills the home feed with game and app-download offers the member can start, each carrying a headline payout amount in the account currencyCode.
Auth: Bearer accessToken from Login. operationName=UserOfferSuggestions.
- userOfferSuggestions
- offers
- id
- targetingId
- title
- targetDeviceType
- isSpecialPromotion
- category
- isAppDownload
- payout
- amount
- currencyCode
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "operationName": "UserOfferSuggestions", "query": "query UserOfferSuggestions($offerSuggestionsData: UserOfferSuggestionsInput!) { userOfferSuggestions(offerSuggestionsData: $offerSuggestionsData) { success offers { id targetingId title targetDeviceType imageUrl isSpecialPromotion category { name isAppDownload } payout { amount currencyCode } } } }", "variables": { "offerSuggestionsData": { "targetDeviceType": "AndroidApp", "limit": 20 } } }{ "data": { "userOfferSuggestions": { "success": true, "offers": [ { "id": "off-4412", "targetingId": "tgt-19", "title": "Reach level 20 in Castle Raid", "targetDeviceType": "AndroidApp", "imageUrl": "https://cdn.testerup.com/offers/castle.png", "isSpecialPromotion": false, "category": { "name": "Games", "isAppDownload": true }, "payout": { "amount": 18.5, "currencyCode": "USD" } } ] } } }Offer detail and goal payouts
POST
/graphql/opendataOpens an offer card into install/play goals: each goal's displayName, timeLimitHours and per-goal payout, plus in-app-purchase cashbackRatioPercentage when the goal is a purchase event.
Auth: Bearer accessToken from Login. operationName=Offer.
- offer
- title
- trackingUrl
- maxTimeToComplete
- hasStreak
- multiplier
- totalReward
- goals
- displayName
- isStartEvent
- isInAppPurchase
- isTimeGated
- timeLimitHours
- cashbackRatioPercentage
- requirements
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "operationName": "Offer", "query": "query Offer($offerData: OfferInput!) { offer(offerData: $offerData) { success offer { id title description trackingUrl maxTimeToComplete hasStreak multiplier payout { amount currencyCode } totalReward { amount currencyCode } category { name isAppDownload } goals { id displayName isStartEvent isInAppPurchase isTimeGated timeLimitHours payout { amount currencyCode } cashbackRatioPercentage } requirements { heading description } } } }", "variables": { "offerData": { "id": "off-4412" } } }{ "data": { "offer": { "success": true, "offer": { "id": "off-4412", "title": "Reach level 20 in Castle Raid", "description": "Install, open and reach level 20 within 14 days.", "trackingUrl": "https://track.testerup.com/c/4412", "maxTimeToComplete": 336, "hasStreak": true, "multiplier": 1, "payout": { "amount": 4.0, "currencyCode": "USD" }, "totalReward": { "amount": 18.5, "currencyCode": "USD" }, "category": { "name": "Games", "isAppDownload": true }, "goals": [ { "id": "g-1", "displayName": "Install and open", "isStartEvent": true, "isInAppPurchase": false, "isTimeGated": false, "timeLimitHours": null, "payout": { "amount": 4.0, "currencyCode": "USD" }, "cashbackRatioPercentage": null }, { "id": "g-2", "displayName": "Reach level 20", "isStartEvent": false, "isInAppPurchase": false, "isTimeGated": true, "timeLimitHours": 336, "payout": { "amount": 14.5, "currencyCode": "USD" }, "cashbackRatioPercentage": null } ], "requirements": [ { "heading": "New players only", "description": "Device must not have installed Castle Raid before." } ] } } } }In-progress tasks
POST
/graphql/opendataPages the My Tasks list: each started offer with goalConversions status (CREDITED vs PENDING) and an optional play streak currentDay.
Auth: Bearer accessToken from Login. operationName=AllTasks.
- allTasks
- total
- pages
- tasks
- offerTitle
- status
- startedAt
- userParticipationId
- totalReward
- goalConversions
- goalId
- reward
- streak
- currentDay
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "operationName": "AllTasks", "query": "query AllTasks($tasksData: AllTasksInput!) { allTasks(tasksData: $tasksData) { success total pages tasks { id offerTitle status startedAt maxTimeToComplete userParticipationId totalReward { amount currencyCode } goalConversions { goalId status reward currencyCode type isStartEvent } streak { currentDay totalDays status } } } }", "variables": { "tasksData": { "page": 1, "limit": 20, "status": "IN_PROGRESS" } } }{ "data": { "allTasks": { "success": true, "total": 2, "pages": 1, "tasks": [ { "id": "task-901", "offerTitle": "Reach level 20 in Castle Raid", "status": "IN_PROGRESS", "startedAt": "2026-10-20T18:02:00Z", "maxTimeToComplete": 336, "userParticipationId": "up-771", "totalReward": { "amount": 18.5, "currencyCode": "USD" }, "goalConversions": [ { "goalId": "g-1", "status": "CREDITED", "reward": 4.0, "currencyCode": "USD", "type": "INSTALL", "isStartEvent": true }, { "goalId": "g-2", "status": "PENDING", "reward": 14.5, "currencyCode": "USD", "type": "LEVEL", "isStartEvent": false } ], "streak": { "currentDay": 3, "totalDays": 7, "status": "ACTIVE" } } ] } } }Task detail and claimable conversions
POST
/graphql/opendataLoads one started task so the member can see which goalConversions have credited, which still decay at nextDecayAt, and whether in-app-purchase cashback still applies.
Auth: Bearer accessToken from Login. operationName=Task. Claiming a credited conversion is a follow-up ClaimGoalConversion mutation with the same Bearer.
- task
- areRewardsChangeable
- title
- expiresAt
- isExpired
- goalConversions
- displayName
- status
- reward
- nextDecayAt
- nextReward
- purchaseValue
- cashbackRatioPercentage
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "operationName": "Task", "query": "query Task($taskData: UserTaskInput!) { task(taskData: $taskData) { success status areRewardsChangeable task { id title status trackingUrl expiresAt isExpired totalReward { amount currencyCode } goalConversions { id goalId displayName status reward currencyCode isTimeGated nextDecayAt nextReward isInAppPurchase purchaseValue cashbackRatioPercentage } } } }", "variables": { "taskData": { "id": "task-901" } } }{ "data": { "task": { "success": true, "status": "IN_PROGRESS", "areRewardsChangeable": false, "task": { "id": "task-901", "title": "Reach level 20 in Castle Raid", "status": "IN_PROGRESS", "trackingUrl": "https://track.testerup.com/c/4412", "expiresAt": "2026-11-03T18:02:00Z", "isExpired": false, "totalReward": { "amount": 18.5, "currencyCode": "USD" }, "goalConversions": [ { "id": "gc-12", "goalId": "g-1", "displayName": "Install and open", "status": "CREDITED", "reward": 4.0, "currencyCode": "USD", "isTimeGated": false, "nextDecayAt": null, "nextReward": null, "isInAppPurchase": false, "purchaseValue": null, "cashbackRatioPercentage": null } ] } } } }Survey catalog
POST
/graphql/opendataLists partner surveys with surveyDuration minutes and the cash reward shown before the member starts.
Auth: Bearer accessToken from Login. operationName=Surveys.
- surveys
- id
- url
- surveyDuration
- reward
- amount
- currencyCode
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "operationName": "Surveys", "query": "query Surveys { surveys { success surveys { id url surveyDuration reward { amount currencyCode } } } }" }{ "data": { "surveys": { "success": true, "surveys": [ { "id": "sv-2201", "url": "https://surveys.testerup.com/s/2201", "surveyDuration": 12, "reward": { "amount": 1.2, "currencyCode": "USD" } } ] } } }Link PayPal identity
POST
/graphql/openfinanceStores the PayPal name/email/country the wallet will send to, after the member finishes the paypal-auth screen.
Auth: Bearer accessToken from Login. operationName=CreatePayPalIdentity. Used from the /paypal-auth route before the first PayPal CreatePayout.
- createPayPalIdentity
- paypalIdentity
- id
- userId
- identifier
- firstName
- lastName
- country
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "operationName": "CreatePayPalIdentity", "query": "mutation CreatePayPalIdentity($paypalIdentity: PayPalIdentityInput!) { createPayPalIdentity(paypalIdentity: $paypalIdentity) { success paypalIdentity { id userId identifier firstName lastName email country } } }", "variables": { "paypalIdentity": { "email": "[email protected]", "firstName": "Maya", "lastName": "Keller", "country": "US" } } }{ "data": { "createPayPalIdentity": { "success": true, "paypalIdentity": { "id": "pp-331", "userId": "u-88421", "identifier": "PP-MAYA", "firstName": "Maya", "lastName": "Keller", "email": "[email protected]", "country": "US" } } } }Request payout
POST
/graphql/openfinanceDeducts a published threshold amount from wallet.balance and opens a payout in PAYPAL, AMAZON_GIFT_CARD, VENMO or VISA_VIRTUAL_CARD, returning netAmount after any feeRate.
Auth: Bearer accessToken from Login. operationName=CreatePayout. Face-scan verification may be required first (faceScanVerification.isVerified on Me).
- createPayout
- payout
- id
- type
- status
- createdAt
- paymentProvider
- netAmount
- total
- amount
- currencyCode
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "operationName": "CreatePayout", "query": "mutation CreatePayout($createPayoutInput: PayoutInput!) { createPayout(createPayoutInput: $createPayoutInput) { success payout { id type status createdAt payinType paymentProvider netAmount total { amount currencyCode } } } }", "variables": { "createPayoutInput": { "paymentProvider": "PAYPAL", "amount": 60, "currencyCode": "USD" } } }{ "data": { "createPayout": { "success": true, "payout": { "id": "po-1008", "type": "STANDARD", "status": "PENDING", "createdAt": "2026-10-23T12:40:00Z", "payinType": null, "paymentProvider": "PAYPAL", "netAmount": 60.0, "total": { "amount": 60.0, "currencyCode": "USD" } } } } }Face-scan session for payout KYC
POST
/graphql/osintStarts the face-verification camera flow required before some payouts; maxAttemptsReached maps to the /max-attempts-reached screen.
Auth: Bearer accessToken from Login. operationName=FaceScanSessionToken. The returned sessionToken is posted to ProcessFaceScan; Me.faceScanVerification.isVerified gates CreatePayout.
- faceScanSessionToken
- success
- maxAttemptsReached
- sessionToken
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "operationName": "FaceScanSessionToken", "query": "query FaceScanSessionToken($userAgent: String!) { faceScanSessionToken(userAgent: $userAgent) { success maxAttemptsReached sessionToken } }", "variables": { "userAgent": "Testerup Android 3.2.10" } }{ "data": { "faceScanSessionToken": { "success": true, "maxAttemptsReached": false, "sessionToken": "fs_sess_9c21..." } } }Referral invite code
POST
/graphql/opendataMints the shareable invite.code / invite.link shown after referralUnlockedAt, with valueTier matching Me.referralReward.
Auth: Bearer accessToken from Login. operationName=CreateReferralInvite.
- createReferralInvite
- invite
- code
- valueTier
- link
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "operationName": "CreateReferralInvite", "query": "mutation CreateReferralInvite { createReferralInvite { success invite { code valueTier link } } }" }{ "data": { "createReferralInvite": { "success": true, "invite": { "code": "MAYA8", "valueTier": "STANDARD", "link": "https://www.testerup.com/invite?code=MAYA8" } } } }Daily account streak
POST
/graphql/opendataDrives the home streak widget: currentDay toward milestoneIntervalDays, today's pendingRewards, and the eligibleGames that still count as a play for the streak.
Auth: Bearer accessToken from Login. operationName=AccountStreak. A follow-up ClaimAccountStreakReward mutation credits the pending day/tier.
- accountStreak
- status
- currentDay
- milestoneIntervalDays
- isTodayCounted
- resetsAt
- minEarning
- maxDailyReward
- pendingRewards
- eligibleGames
POST /graphql/ HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "operationName": "AccountStreak", "query": "query AccountStreak { me { success user { id accountStreak { status currentDay milestoneIntervalDays isTodayCounted resetsAt minEarning { amount currencyCode } maxDailyReward { amount currencyCode } pendingRewards { day currency tiers { amount } } eligibleGames { id title totalReward { amount currencyCode } } } } } }" }{ "data": { "me": { "success": true, "user": { "id": "u-88421", "accountStreak": { "status": "ACTIVE", "currentDay": 4, "milestoneIntervalDays": 7, "isTodayCounted": true, "resetsAt": "2026-10-24T07:00:00Z", "minEarning": { "amount": 1.0, "currencyCode": "USD" }, "maxDailyReward": { "amount": 0.4, "currencyCode": "USD" }, "pendingRewards": [ { "day": 4, "currency": "USD", "tiers": [{ "amount": 0.25 }] } ], "eligibleGames": [ { "id": "off-4412", "title": "Castle Raid", "totalReward": { "amount": 18.5, "currencyCode": "USD" } } ] } } } } }
Data categories
- user profiles
- wallets
- payout methods
- payout requests
- offer catalog
- task progress
- surveys
- face-scan KYC
- referrals
- account streaks
Where teams use this data
Reconcile PayPal and gift-card payouts
Treasury bots read payoutThresholds and paymentOptions.method/feeRate, then match CreatePayout.netAmount and paymentProvider (PAYPAL, AMAZON_GIFT_CARD, VENMO, VISA_VIRTUAL_CARD) against wallet.totalPaidOut and openPayoutAmount so a $60 rung that left the wallet is closed.
Score offer goals versus pending credit
Workforce analytics join Offer.goals.payout.amount and isTimeGated/timeLimitHours with AllTasks.goalConversions.status so a LEVEL goal still PENDING is not treated as cashable balance.
Gate cashout on face-scan KYC
Compliance stacks hide the payout-form submit when Me.faceScanVerification.isVerified is false or maxAttemptsReached is true, matching the /face-verification camera step the privacy policy requires before some payouts.
Meter streak eligibility against the game catalog
Ops dashboards subtract AccountStreak.minEarning from eligibleGames.totalReward so a day that did not clear the floor is not counted toward currentDay or pendingRewards.
Frequently asked questions
Which fields distinguish Testerup wallet funds from pending payouts?
The member record separates balance, openPayoutAmount and totalPaidOut. It also includes currencyCode, payoutThresholds and paymentOptions with method and feeRate. Payout records add paymentProvider, netAmount, status and createdAt, so reconciliation can distinguish an outstanding withdrawal from a completed payment. The illustrated payment methods include PAYPAL, AMAZON_GIFT_CARD, VENMO and VISA_VIRTUAL_CARD.
Can goal progress and expiring rewards be tracked separately?
Yes. Offer goals include displayName, isInAppPurchase, isTimeGated and timeLimitHours. Started tasks carry goalConversions with goalId, status and reward, including PENDING and CREDITED states. Task detail adds expiresAt, isExpired, nextDecayAt, nextReward, purchaseValue and cashbackRatioPercentage. These fields support progress and deadline tracking without treating pending goal rewards as available wallet balance.
What survey, streak and referral data is included?
Survey records include surveyDuration and reward with amount and currencyCode. Account-streak records include currentDay, milestoneIntervalDays, isTodayCounted, resetsAt, minEarning, maxDailyReward, pendingRewards and eligibleGames. Referral data includes referralCount and an invite with code, valueTier and link. These records support survey reward comparisons, streak-status views and referral tracking.
Do these examples describe a public, unauthenticated Testerup API?
No. The documented member, wallet, task and payout operations require a Bearer accessToken from sign-in. Email login can return a twoFactor challenge with challengeId, maskedEmail and expiresAt; some payouts also require face verification. The examples describe the app's data model and authenticated flows, not an official public developer program or anonymous access to member records.
Apps similar to Testerup: Test & Earn Rewards
- Freecash: Earn Money — Freecash is Almedia's GPT rewards app, often compared with Testerup, where members play games, complete surveys and try offers, then cash out via PayPal, Venmo, gift cards or crypto.
- Swagbucks — Swagbucks is Prodege's rewards portal that combines games with surveys, cashback, videos and web search, then pays members in gift cards or PayPal.
- InboxDollars — InboxDollars is a rewards site listed among apps like Testerup, where members earn cash from games, surveys, reading paid emails and shopping, then cash out via PayPal or gift cards.
- JustPlay — JustPlay is a free Android and iOS gaming-rewards app that awards loyalty coins for playing games and lets members redeem them for PayPal cash, gift cards or charity donations.
- Mistplay — Mistplay is a free Android and iOS app that awards points for installing and playing games from its catalog and lets members redeem those points as PayPal cash or gift cards from brands such as Amazon, Walmart and Google Play.
- UserTesting — UserTesting is a paid-testing network named as a Testerup alternative, where participants complete surveys, recorded usability tests and live video sessions and are paid via PayPal.
- Cash Giraffe — Cash Giraffe is justDice's Android and iOS rewards app that pays gems for playing featured games and taking surveys, redeemable as PayPal cash or gift cards from a $0.20 minimum.
Topics
- Testerup data API
- Testerup endpoints and fields
- Testerup wallet balance
- Testerup payout reconciliation
- Testerup goal conversion status
- Testerup survey rewards
- Testerup account streak data
- aestimium GmbH Testerup
Need this app's data API integrated?
We deliver scoped integrations for any named app — from USD 500 with source-code handoff, or hosted access billed per call. Tell us the data you need.
- NDA + SOW on every engagement
- Delivery in 3–7 days
- Payment only after acceptance
- Work scoped to authorized use